home *** CD-ROM | disk | FTP | other *** search
- (********** #File "CLIP_UNIX.PAS" (#Indent on, #Comment on) *******)
- (*********************************************************************)
- (* Program: CLIP_2 - Code from LIterate Program: 2-nd pass *)
- (* Purpose: Perform a run of the CLIP-system. *)
- (* Interface: CLIP.INI: File which contains all the information *)
- (* for this particular run. *)
- (* <sources>: Files containing the refinements. *)
- (* <modules>: Files containing the generated modules. *)
- (*********************************************************************)
- PROGRAM CLIP_2 (INPUT, OUTPUT);
- (*----------- Global parameters of the CLiP system ---------------*)
- CONST
- CLiP = 'Code from Literate Programs';
- CLIP_VERSION = 'CLiP version 2.1'; (* Mod: EWvA 16/10/93 *)
- DFLT_INIFILE = 'CLIP.INI'; (* Mod: EWvA 16/10/93 *)
- DFLT_INIFILE_L = 8; (* Mod: EWvA 16/10/93 *)
- STRING_FIXED_L = 132;
- EMPTY_STRING_FIXED = ' '+
- ' '+
- ' ';
- MAX_FILE_SPEC_L = 132;
- MAX_NR_FILE_SPECS = 64;
- MAX_CHOICE_L = 100;
- ALLOWED_ID_CHARS = ['A'..'Z', 'a'..'z', '0'..'9', '.'];
- ERROR_MSG_LENGTH = 80;
- LOC_SPEC_L = 25;
- CORRUPT_INI_FILE = 1; (* Error_code used by CLIP_MNU *)
- FT_SIZE = MAX_NR_FILE_SPECS;
- MAX_LINE = 132;
- ST_SIZE = 30000;
- SP_SIZE = 65000;
- SYNTAX_LEN = 10;
- MAX_MODE_L = 16;
- MAX_M_D_L = 10;
- MAX_NR_SRC_FILES = MAX_NR_FILE_SPECS;
- MAX_NR_RSLT_MODULES = 10;
- MAX_EXTR_MODE_L = 9;
- MAX_FILE_EXT_L = 39;
- MAX_OPTION_LENGTH = 15;
- MAX_OPTIONS = 12;
-
- (*----------- Constants to assist implemention of ADTs -----------*)
- CONST
- MAX_NR_MESS = 35;
- MAX_ERROR = 100;
- CONST
- EMPTY_OPTION = ' ';
-
- (*----------- Global simple types of the CLiP system -------------*)
- TYPE
- TO_BE_DECIDED_LATER_ = (DEFINED,UNDEFINED);
- LONGINTEGER = -2147483647..2147483647;
- STRING_FIXED_ = PACKED ARRAY[1..STRING_FIXED_L] OF CHAR;
- FILE_MODE_ = (INSP_MODE, GEN_MODE);
- SPECIAL_CHOICE_ = CHAR;
- ALLOWED_ANSW_ = SET OF CHAR;
- ERROR_MSG_ = STRING_FIXED_;
- SEV_CODE_ = (WARN, ERR, FAIL, DUMP);
- LOC_SPEC_ = PACKED ARRAY[1..LOC_SPEC_L] OF CHAR;
- FT_INDEX_ = 0..FT_SIZE;
- ERROR_CODE_ = INTEGER;
- ST_INDEX_ = -1..ST_SIZE;
- SEGMENT_TYPE_ = (STUB, SLOT, CODE, END_STUB);
- SP_INDEX_ = -1..SP_SIZE;
- SYNTAX_STRING_ = STRING_FIXED_;
- MODE_ = STRING_FIXED_;
- MESSAGE_DESTINATION_ = STRING_FIXED_;
- EXTR_MODE_ = STRING_FIXED_;
- FILE_EXT_ = STRING_FIXED_;
- CATEGORY_ = (L1, L2, L3, L4, L5);
- SLT_PTR_ = ^SLOT_DES_;
- STB_PTR_ = ^STUB_DES_;
- SHADOW_PTR_ = ^SHADOW_LIST_;
-
- (*----------- Global structured types of the CLiP system ---------*)
- STRING132_ = RECORD
- BODY: STRING_FIXED_;
- LENGTH: INTEGER;
- END (*RECORD*);
- FILE_SPEC_ = RECORD
- LENGTH: INTEGER;
- BODY: STRING_FIXED_;
- END (*RECORD*);
- RSLT_MOD_SPEC_ = RECORD
- FILE_NAME: FILE_SPEC_;
- PATH: FILE_SPEC_;
- END (*RECORD*);
- SOURCE_FILES_ = ARRAY[1..MAX_NR_SRC_FILES] OF FILE_SPEC_;
- RSLT_MODULES_ = ARRAY[1..MAX_NR_RSLT_MODULES] OF
- RSLT_MOD_SPEC_;
- FILE_SPECS_ = RECORD
- NR_FILE_SPECS: INTEGER;
- FILES: SOURCE_FILES_;
- END (*RECORD*);
- LINE_DES_ = RECORD
- CHARS: STRING_FIXED_;
- INDENT: INTEGER;
- USED: INTEGER;
- ID: INTEGER;
- POS_OPTION_MARKER: INTEGER;
- END (*RECORD*);
- SEGMENT_DES_ = RECORD
- FIRST: ST_INDEX_;
- LAST: ST_INDEX_;
- END (*RECORD*);
- STRING_DES_ = RECORD
- FIRST: SP_INDEX_;
- LAST: SP_INDEX_;
- END (*RECORD*);
- SYNTAX_ = RECORD
- BODY: SYNTAX_STRING_;
- LENGTH: INTEGER;
- END (*RECORD*);
- RUN_INFO_ = RECORD
- CLIP_LPAR,
- CLIP_RPAR: SYNTAX_;
- CLIP_CC: CHAR;
- CLIP_END: SYNTAX_;
- OPTION_MARKER: CHAR;
- MODE: MODE_;
- INT_FAULT_CORR: BOOLEAN;
- MESSAGE_DESTINATION: MESSAGE_DESTINATION_;
- REPORT_FILE_SPEC: FILE_SPEC_;
- NR_SRC_FILES: INTEGER;
- SOURCE_FILES: SOURCE_FILES_;
- EXTR_MODE: EXTR_MODE_;
- NR_MODULES: INTEGER;
- RSLT_MODULES: RSLT_MODULES_;
- DFLT_EXT: FILE_EXT_;
- MODULE_DIRECTORY: FILE_SPEC_;
- END (*RECORD*);
- LINE_INFO_ = RECORD
- LINE_ID: STRING_DES_;
- CATEGORY: CATEGORY_;
- OPTIONS: BOOLEAN;
- END (*RECORD*);
- OPTIONS_ = RECORD
- QUICK, MULTIPLE, OPTIONAL, OVERRULE,
- LEADER, TRAILER, SEPARATOR, DEFAULT,
- LINENUMBER: BOOLEAN;
- INDENT,
- FILE_NAME,
- COMMENT: STRING_DES_;
- END (*RECORD*);
- STUB_DES_ = RECORD
- NAME: STRING_DES_ ;
- SRC_IMG: SEGMENT_DES_;
- OPTIONS: OPTIONS_ ;
- SLOTS: SLT_PTR_ ;
- NEXT_TWIN,
- NEXT_STUB: STB_PTR_ ;
- VISITED: BOOLEAN ;
- END (*RECORD*);
- SLOT_DES_ = RECORD
- NAME: STRING_DES_;
- SRC_IMG: SEGMENT_DES_;
- OPTIONS: OPTIONS_;
- STUB_REF: STB_PTR_;
- CODE: SEGMENT_DES_;
- NEXT_SLOT: SLT_PTR_;
- END (*RECORD*);
- CODE_STRUCT_ = RECORD
- FIRST_STUB: STB_PTR_;
- LAST_STUB: STB_PTR_;
- END (*RECORD*);
- SHADOW_LIST_ = RECORD
- STUB_POINTER: STB_PTR_;
- NEXT: SHADOW_PTR_;
- END (*RECORD*);
-
- (*----------- Types to assist implemention of ADTs ---------------*)
- TYPE
- SP_TYPE = RECORD
- CHARS: ARRAY[1..SP_SIZE] OF CHAR;
- USED : SP_INDEX_;
- END (*RECORD*);
- SP_PTR = ^SP_TYPE;
- TYPE
- OPTION_KEYWORD_ = PACKED ARRAY [1..MAX_OPTION_LENGTH] OF CHAR;
-
- (*----------- Global variables of the CLiP system ----------------*)
- VAR
- REPORT_FILE: TEXT;
- REPORT_OK: BOOLEAN;
-
- (*----------- Variables to assist implemention of ADTs -----------*)
- VAR
- START, STOP: LONGINTEGER;
- CONTINUE: BOOLEAN;
- RUN_INFO: RUN_INFO_;
- CODE_STRUCT: CODE_STRUCT_;
- (* STRING132: STRING132_; 22/10/93 *)
- (* DUMMY_LINE: LINE_DES_; 22/10/93 *)
- (* DUMMY_SEG: SEGMENT_DES_; 22/10/93 *)
- DUMMY_ERROR: INTEGER;
- INI_FILE: TEXT;
- EXT_FILE_SPEC: FILE_SPEC_;
- DUMMY_FILE_OK: BOOLEAN;
- DUMMY_ERROR_MSG: ERROR_MSG_;
- DUMMY_ERROR_CODE: INTEGER;
- ERROR_CODE: ERROR_CODE_;
- AUX_STRING_8: PACKED ARRAY[1..8] OF CHAR;
- I: INTEGER;
- ERROR_MSG : ERROR_MSG_;
- VAR
- FILE_TABLE: ARRAY[1..FT_SIZE] OF RECORD
- FILE_SPEC: FILE_SPEC_;
- FIRST: INTEGER;
- LAST: INTEGER;
- END (*RECORD*);
- LAST_LINE: INTEGER;
- LAST_FILE: FT_INDEX_;
- CURR_IN_FILE: TEXT;
- CURR_OUT_FILE: TEXT;
- SPACE: SET OF CHAR;
- VAR
- SEGMENT_TABLE: RECORD
- LINES: ARRAY [1..ST_SIZE] OF LINE_DES_;
- USED: ST_INDEX_;
- END (*RECORD*);
- LAST_READ_SEG: RECORD
- LAST_SEG: SEGMENT_DES_;
- LAST_LINE: ST_INDEX_;
- END (*RECORD*);
- VAR
- STRING_POOL: SP_PTR;
- BUFFER: STRING132_;
- VAR
- DIAG_TBL: ARRAY[1..MAX_NR_MESS] OF
- RECORD
- MESSAGE: STRING_FIXED_;
- MESS_LOC: LOC_SPEC_;
- MESS_L: INTEGER;
- END (*RECORD*);
- NO_MESSAGES: BOOLEAN;
- MSG_TBL: ARRAY[1..MAX_ERROR+1] OF
- RECORD
- SEV: SEV_CODE_;
- LOC: LOC_SPEC_;
- SOURCE_LINE: LINE_DES_;
- SEGMENT: SEGMENT_DES_;
- STRING132: STRING132_;
- LINE_ABS: INTEGER;
- END (*RECORD*);
- NR_MSG: INTEGER;
- VAR
- ALLOWED: SET OF CHAR;
- VAR
- OPTION_TABLE: ARRAY [1..MAX_OPTIONS] OF OPTION_KEYWORD_;
- OPT_SPACE: SET OF CHAR;
- OPT_CHARS: SET OF CHAR;
- DEFAULT_OPTIONS: OPTIONS_;
- PASCAL_STRING: STRING_FIXED_;
- FORTRAN_STRING: STRING_FIXED_;
- C_STRING: STRING_FIXED_;
-
- (*----------- Forward declarations -------------------------------*)
- PROCEDURE CLIP_STOP; FORWARD;
- PROCEDURE EXT_FILE_CLOSE( VAR FILE_VAR : TEXT;
- VAR ERROR_CODE: INTEGER); FORWARD;
- PROCEDURE EXT_FILE_PREP (VAR FILE_VAR: TEXT;
- EXT_FILE_SPEC: FILE_SPEC_;
- FILE_MODE: FILE_MODE_;
- VAR FILE_OK: BOOLEAN;
- VAR ERROR_CODE: INTEGER;
- VAR ERROR_MSG: ERROR_MSG_ );
- FORWARD;
- PROCEDURE READ_FILE_SPEC (VAR AUX_FILE_SPEC: FILE_SPEC_;
- VAR FILE_SPEC_OK: BOOLEAN);
- FORWARD;
- PROCEDURE UC_WORD (VAR STR: PACKED ARRAY [ONE..LEN:INTEGER]
- OF CHAR); FORWARD;
- PROCEDURE WRITE_STRING (VAR OUT_FILE: TEXT;
- OUT_STRING: STRING_FIXED_;
- NR_CHARS: INTEGER); FORWARD;
- PROCEDURE WRLN_STRING (VAR OUT_FILE: TEXT;
- OUT_STRING: STRING_FIXED_;
- NR_CHARS: INTEGER;
- SPACE: INTEGER); FORWARD;
- FUNCTION CHECK_SYNTAX (LPAR, RPAR, END_STRING: SYNTAX_;
- CC, MARKER: CHAR): BOOLEAN;
- FORWARD;
- PROCEDURE INIT_RUN_INFO (VAR INIT_INFO: RUN_INFO_);
- FORWARD;
- PROCEDURE READ_INI_FILE (VAR INI_FILE: TEXT;
- VAR READ_INFO: RUN_INFO_;
- EXT_FILE_SPEC: FILE_SPEC_;
- VAR FILE_OK: BOOLEAN;
- VAR ERROR_MSG: ERROR_MSG_;
- VAR ERROR_CODE: INTEGER);
- FORWARD;
- PROCEDURE READ_LINE_SAFELY (VAR FILE_IN: TEXT);
- FORWARD;
- PROCEDURE READ_STRING (VAR IN_FILE: TEXT;
- VAR IN_STR_LN: INTEGER;
- VAR IN_STR_BODY: STRING_FIXED_;
- NR_CHARS_TO_READ: INTEGER);
- FORWARD;
- FUNCTION UC (INCHAR: CHAR): CHAR;
- FORWARD;
- PROCEDURE VAL_INI_DATA (VAR VAL_INFO: RUN_INFO_;
- VAR OK: BOOLEAN);
- FORWARD;
- FUNCTION FT_ABS_LINE_NUMBER (SOURCE_LINE: LINE_DES_): INTEGER;
- FORWARD;
- FUNCTION FT_CHECK_FILE (FILE_SPEC: FILE_SPEC_): ERROR_CODE_;
- FORWARD;
- FUNCTION FT_EOF: BOOLEAN;
- FORWARD;
- FUNCTION FT_GET_CHAR (SOURCE_LINE: LINE_DES_; INDEX: INTEGER): CHAR;
- FORWARD;
- PROCEDURE FT_GET_FILE_SPEC
- (SOURCE_LINE:LINE_DES_; VAR FILE_SPEC:FILE_SPEC_);
- FORWARD;
- FUNCTION FT_GET_INDENT (SOURCE_LINE: LINE_DES_): INTEGER;
- FORWARD;
- FUNCTION FT_GET_LINE_LENGTH (SOURCE_LINE: LINE_DES_): INTEGER;
- FORWARD;
- FUNCTION FT_GET_LINE_NUMBER (SOURCE_LINE: LINE_DES_): INTEGER;
- FORWARD;
- FUNCTION FT_GET_POS_OPTION_MARKER (SOURCE_LINE: LINE_DES_): INTEGER;
- FORWARD;
- FUNCTION FT_INCLOSE: ERROR_CODE_;
- FORWARD;
- PROCEDURE FT_INIT;
- FORWARD;
- PROCEDURE FT_INIT_LINE (VAR LINE: LINE_DES_);
- FORWARD;
- FUNCTION FT_INOPEN (FILE_SPEC: FILE_SPEC_): ERROR_CODE_;
- FORWARD;
- FUNCTION FT_OUTOPEN (FILE_SPEC: FILE_SPEC_): ERROR_CODE_;
- FORWARD;
- FUNCTION FT_OUTCLOSE: ERROR_CODE_;
- FORWARD;
- PROCEDURE FT_RDLN (VAR LINE: LINE_DES_);
- FORWARD;
- PROCEDURE FT_WRLN (VAR LINE: LINE_DES_; NR_BLANKS: INTEGER;
- DESTINATION: INTEGER);
- FORWARD;
- FUNCTION ST_ABS_SEG (SEGMENT: SEGMENT_DES_):INTEGER;
- FORWARD;
- PROCEDURE ST_GET_FILE_SPEC ( SEGMENT: SEGMENT_DES_;
- VAR FILE_SPEC: FILE_SPEC_);
- FORWARD;
- FUNCTION ST_GET_INDENT (SEG: SEGMENT_DES_): INTEGER;
- FORWARD;
- PROCEDURE ST_GET_LINE (VAR LINE: LINE_DES_);
- FORWARD;
- PROCEDURE ST_GET_OPTION_LINE (SEG: SEGMENT_DES_; VAR LINE: LINE_DES_);
- FORWARD;
- PROCEDURE ST_GET_SEG (SEG: SEGMENT_DES_; VAR LINE: LINE_DES_);
- FORWARD;
- PROCEDURE ST_GET_SEG_RANGE ( SEGMENT: SEGMENT_DES_;
- VAR FIRST, LAST:INTEGER);
- FORWARD;
- PROCEDURE ST_INIT;
- FORWARD;
- PROCEDURE ST_INIT_SEG (VAR SEG: SEGMENT_DES_);
- FORWARD;
- FUNCTION ST_IS_EMPTY_SEG (SEG: SEGMENT_DES_): BOOLEAN;
- FORWARD;
- FUNCTION ST_NUMBER_OF_LINES (SEG: SEGMENT_DES_): INTEGER;
- FORWARD;
- PROCEDURE ST_PUT_LINE (LINE: LINE_DES_; VAR SEG: SEGMENT_DES_);
- FORWARD;
- PROCEDURE ST_PUT_SEG (LINE: LINE_DES_; VAR SEG: SEGMENT_DES_);
- FORWARD;
- PROCEDURE ST_FINIT;
- FORWARD;
- FUNCTION ST_SEG_WIDTH (SEG: SEGMENT_DES_): INTEGER;
- FORWARD;
- PROCEDURE ST_WRITE_SEG (SEG: SEGMENT_DES_; BLANKS: INTEGER;
- DESTINATION: INTEGER);
- FORWARD;
- PROCEDURE SP_ADD_CHAR (CH: CHAR; VAR STR: STRING_DES_);
- FORWARD;
- PROCEDURE SP_CONC_STR (VAR MASTER: STRING_DES_; SLAVE: STRING_DES_);
- FORWARD;
- FUNCTION SP_EQ (STR1: STRING_DES_; STR2: STRING_DES_): BOOLEAN;
- FORWARD;
- PROCEDURE SP_EXTR_STR (STR: STRING_DES_; VAR STR132: STRING132_);
- FORWARD;
- FUNCTION SP_GET_CHAR (INDEX: INTEGER; STR: STRING_DES_): CHAR;
- FORWARD;
- PROCEDURE SP_INIT;
- FORWARD;
- PROCEDURE SP_INIT_STR (VAR STR: STRING_DES_);
- FORWARD;
- FUNCTION SP_IS_EMPTY_STR (STR: STRING_DES_): BOOLEAN;
- FORWARD;
- FUNCTION SP_LENGTH_STR (STR: STRING_DES_): INTEGER;
- FORWARD;
- PROCEDURE SP_ADD_BUFFER (VAR STR: STRING_DES_);
- FORWARD;
- PROCEDURE SP_ADD_BUFFER_CHAR (CH: CHAR);
- FORWARD;
- FUNCTION SP_GET_BUFFER_CHAR (INDEX: INTEGER): CHAR;
- FORWARD;
- PROCEDURE SP_INIT_BUFFER;
- FORWARD;
-
- (*----------- General routines -----------------------------------*)
-
- (*********************************************************************)
- (* Procedure: CLIP_STOP (VAX-version) *)
- (* Purpose: To halt a program without any message or dump. *)
- (*********************************************************************)
- PROCEDURE CLIP_STOP;
- BEGIN
- HALT
- END (*PROCEDURE CLIP_STOP*);
-
- (*********************************************************************)
- (* Routine: EXT_FILE_CLOSE (VAX-version) *)
- (* Purpose: To close an external file. *)
- (* Interface: FILE_VAR - Pascal file in question *)
- (* ERROR_CODE - Error indication to caller *)
- (*********************************************************************)
- PROCEDURE EXT_FILE_CLOSE;
- BEGIN
- CLOSE (FILE_VAR);
- ERROR_CODE := 0;
- END (*EXT_FILE_CLOSE*);
-
- (*********************************************************************)
- (* Procedure: EXT_FILE_PREP ( VAX-version ) *)
- (* Purpose: To prepare an external file for reading from it *)
- (* or writing to it. *)
- (* Interface: EXT_FILE_SPEC - VMS-file in question. *)
- (* FILE_MODE - Mode indicator. *)
- (* FILE_VAR - Pascal file in question. *)
- (* FILE_OK - Indicates succesfull preparation. *)
- (* ERROR_CODE - Error indication to caller. *)
- (* ERROR_MSG - Error message to caller. *)
- (*********************************************************************)
- PROCEDURE EXT_FILE_PREP;
- VAR
- AUX_FILE_SPEC: VARYING [MAX_FILE_SPEC_L] OF CHAR;
- BEGIN
- ERROR_CODE := -1; (* Initialization *)
- AUX_FILE_SPEC := EXT_FILE_SPEC.BODY;
- IF (FILE_MODE = INSP_MODE) THEN
- BEGIN
- IF (EXT_FILE_SPEC.LENGTH <> 0) THEN
- BEGIN
- (* First the file has to be opened. *)
- OPEN (FILE_VAR,
- AUX_FILE_SPEC,
- 'old',
- ERROR_CODE);
- IF ERROR_CODE = 0 THEN
- RESET (FILE_VAR);
- END (*IF*);
- END
- ELSE
- BEGIN
- (* FILE_MODE is gelijk aan GEN_MODE *)
- IF (EXT_FILE_SPEC.LENGTH <> 0) THEN
- BEGIN
- (* First the file has to be opened. *)
- OPEN (FILE_VAR,
- AUX_FILE_SPEC,
- 'unknown',
- ERROR_CODE);
- IF ERROR_CODE = 0 THEN
- REWRITE (FILE_VAR);
- END (*IF*);
- END (*IF*);
-
- (* DEFAULT CODE: *)
- IF NOT (ERROR_CODE = 0) THEN
- BEGIN
- FILE_OK := FALSE;
- (* This string is a bit too short for the assignment, *)
- (* but that is no problem in VAX-Pascal. *)
- CASE ERROR_CODE OF
- -1: BEGIN
- ERROR_MSG := 'Empty file name.';
- END;
- 2: BEGIN
- ERROR_MSG := 'File not found.';
- END;
- OTHERWISE
- ERROR_MSG := 'Unsuccesful performance';
- END (*CASE*);
- END (*IF*)
- ELSE
- BEGIN
- FILE_OK := TRUE;
- ERROR_MSG := 'Succesful performance. ';
- ERROR_CODE := 0;
- END (*IF*);
- (* END DEFAULT CODE *)
-
- END (*EXT_FILE_PREP*);
-
- (*********************************************************************)
- (* Procedure: READ_FILE_SPEC *)
- (* Purpose: To read a filespecification from the terminal. *)
- (* Interface: AUX_FILE_SPEC - Returned file specification. *)
- (* FILE_SPEC_OK - File specification from terminal. *)
- (* Author/Date: Maarten Rooda, January 1991. *)
- (*********************************************************************)
- PROCEDURE READ_FILE_SPEC;
- VAR
- VAX_AUX_FILE_SPEC: VARYING [MAX_FILE_SPEC_L] OF CHAR;
- I: INTEGER; (* loopvariable. *)
- DUMMY_FILE: TEXT;
- FILE_OK: BOOLEAN;
- ERROR_CODE: INTEGER;
- ERROR_MSG: ERROR_MSG_;
-
- BEGIN
- FILE_SPEC_OK := TRUE;
- READLN (VAX_AUX_FILE_SPEC);
- FOR I := 1 TO LENGTH(VAX_AUX_FILE_SPEC) DO
- BEGIN
- AUX_FILE_SPEC.BODY[I] := VAX_AUX_FILE_SPEC[I];
- END (*FOR*);
- AUX_FILE_SPEC.LENGTH := LENGTH(VAX_AUX_FILE_SPEC)
- END (*PROCEDURE READ_FILE_SPEC*);
-
- (*********************************************************************)
- (* Routine: UC_WORD *)
- (* Pupose: To convert a string to upper case . *)
- (* Interface: STRING - String to be converted *)
- (*********************************************************************)
- PROCEDURE UC_WORD;
- VAR
- COUNTER: INTEGER;
- BEGIN
- FOR COUNTER := ONE TO LEN DO
- STR[COUNTER] := UC (STR[COUNTER]);
- END (*UC_WORD*);
-
- (*********************************************************************)
- (* Procedure: WRITE_STRING (VAX-version) *)
- (* Purpose: Write a part of a text string to a text file *)
- (* Interface: OUT_FILE - The file that is written to *)
- (* NR_CHARS - The number of CHAR's that have to be *)
- (* written to the file *)
- (* OUT_STRING - The string to be written *)
- (* Author/date: Hans Rabouw, March 1992 *)
- (*********************************************************************)
- PROCEDURE WRITE_STRING;
- VAR
- I: INTEGER;
- BEGIN
- FOR I:= 1 TO NR_CHARS DO
- WRITE(OUT_FILE, OUT_STRING[I]);
- END;
-
- (*********************************************************************)
- (* Routine: WRLN_STRING - WRiTeLN STRING. (VAX-version) *)
- (* Purpose: Write a part of a text string to a text file and *)
- (* jump to the next line in the file after that. *)
- (* Interface: OUT_FILE - The file that is written to *)
- (* NR_CHARS - The number of CHAR's that have to be *)
- (* written to the file *)
- (* OUT_STRING - The string to be written *)
- (* SPACE - Number of spaces written before string. *)
- (* Author/date: Heleen Hollenberg, june 1992. *)
- (*********************************************************************)
- PROCEDURE WRLN_STRING;
- VAR
- I: INTEGER;
- BEGIN
- FOR I := 1 TO SPACE DO
- WRITE (OUT_FILE, ' ' );
- FOR I:= 1 TO NR_CHARS DO
- WRITE (OUT_FILE, OUT_STRING[I]);
- WRITELN (OUT_FILE);
- END;
-
- (*********************************************************************)
- (* Routine: READ_LINE_SAFELY *)
- (* Purpose: To read a line from a file . *)
- (* Interface: FILE_IN - File to be read *)
- (* Author/date: Boudewijn Pelt, August 1991. *)
- (*********************************************************************)
- PROCEDURE READ_LINE_SAFELY;
- BEGIN
- IF NOT EOF (FILE_IN) THEN
- READLN (FILE_IN);
- END (*READ_LINE_SAFELY*);
-
- (*********************************************************************)
- (* Routine: CHECK_SYNTAX *)
- (* Purpose: To check the syntax parameters of CLIP. If they are *)
- (* not legal then the function result is FALSE *)
- (* Interface: LPAR - CLIP Left parenthesis definition *)
- (* RPAR - CLIP Right parenthesis definition *)
- (* END_STRING - End of stub indicator *)
- (* CC - CLIP Control Character *)
- (* MARKER - *)
- (* CHECK_SYNTAX - Show example of CLIP-syntax *)
- (* Author/date: Boudewijn Pelt, July 1991 *)
- (*********************************************************************)
- FUNCTION CHECK_SYNTAX;
- VAR
- COUNTER: INTEGER;
- ERROR: BOOLEAN;
-
- BEGIN
- ERROR := FALSE;
- FOR COUNTER := 1 TO SYNTAX_LEN DO
- IF MARKER IN [LPAR.BODY[COUNTER], RPAR.BODY[COUNTER],
- END_STRING.BODY[COUNTER]] THEN
- ERROR := TRUE;
- IF MARKER = CC THEN
- ERROR := TRUE;
-
- IF LPAR.BODY[LPAR.LENGTH] <> CC THEN
- ERROR := TRUE;
- IF RPAR.BODY[1] <> CC THEN
- ERROR := TRUE;
-
- WITH LPAR DO
- BEGIN
- IF LENGTH <= 1 THEN
- ERROR := TRUE;
- FOR COUNTER := 1 TO LENGTH DO
- IF BODY[COUNTER] IN ALLOWED_ID_CHARS THEN
- ERROR := TRUE;
- END (*WITH*);
- WITH RPAR DO
- BEGIN
- IF LENGTH <= 1 THEN
- ERROR := TRUE;
- FOR COUNTER := 1 TO LENGTH DO
- IF BODY[COUNTER] IN ALLOWED_ID_CHARS THEN
- ERROR := TRUE;
- END (*WITH*);
- WITH END_STRING DO
- BEGIN
- IF LENGTH <= 0 THEN
- ERROR := TRUE;
- FOR COUNTER := 1 TO LENGTH DO
- IF NOT (BODY[COUNTER] IN ALLOWED_ID_CHARS) THEN
- ERROR := TRUE;
- END (*WITH*);
- IF (CC IN ALLOWED_ID_CHARS) OR (CC = ' ') THEN
- ERROR := TRUE;
- IF (MARKER IN ALLOWED_ID_CHARS) OR (MARKER = ' ') THEN
- ERROR := TRUE;
-
- CHECK_SYNTAX := NOT ERROR;
- END (*CHECK_SYNTAX*);
-
- (*********************************************************************)
- (* Procedure: INIT_RUN_INFO . *)
- (* Purpose: To initialize the fields of a record INIT_INFO of *)
- (* type RUN_INFO_ to default values. *)
- (* Interface: INIT_INFO - Structure to initialize. *)
- (* Author/date: Maarten Rooda, January 1991. *)
- (*********************************************************************)
- PROCEDURE INIT_RUN_INFO;
-
- CONST
- AUX_STR_L = MAX_MODE_L;
-
- VAR
- I: INTEGER;
- AUX_STRING: PACKED ARRAY[1..AUX_STR_L] OF CHAR;
-
- BEGIN
- (******* INIT_RUN_INFO body *******)
- WITH INIT_INFO DO
- BEGIN
- (* additional parameters of init_info. *)
- CLIP_LPAR.BODY := EMPTY_STRING_FIXED;
- CLIP_LPAR.BODY[1] := '(';
- CLIP_LPAR.BODY[2] := '*';
- CLIP_LPAR.BODY[3] := '*';
- CLIP_LPAR.LENGTH := 3;
-
- CLIP_RPAR.BODY := EMPTY_STRING_FIXED;
- CLIP_RPAR.BODY[1] := '*';
- CLIP_RPAR.BODY[2] := '*';
- CLIP_RPAR.BODY[3] := ')';
- CLIP_RPAR.LENGTH := 3;
-
- CLIP_END.BODY := EMPTY_STRING_FIXED;
- CLIP_END.BODY[1] := 'E';
- CLIP_END.BODY[2] := 'N';
- CLIP_END.BODY[3] := 'D';
- CLIP_END.BODY[4] := 'O';
- CLIP_END.BODY[5] := 'F';
- CLIP_END.LENGTH := 5;
-
- CLIP_CC := '*';
- OPTION_MARKER := '#';
-
- (* old parameters. *)
- MODE := EMPTY_STRING_FIXED;
- AUX_STRING := 'INTERACTIVE_MODE';
- FOR I := 1 TO MAX_MODE_L DO
- MODE[I] := AUX_STRING[I];
-
- INT_FAULT_CORR := TRUE;
-
- MESSAGE_DESTINATION := EMPTY_STRING_FIXED;
- AUX_STRING := 'TERMINAL ';
- FOR I := 1 TO MAX_M_D_L DO
- MESSAGE_DESTINATION[I] := AUX_STRING[I];
-
- REPORT_FILE_SPEC.BODY := EMPTY_STRING_FIXED;
- REPORT_FILE_SPEC.BODY[1] := 'C';
- REPORT_FILE_SPEC.BODY[2] := 'L';
- REPORT_FILE_SPEC.BODY[3] := 'I';
- REPORT_FILE_SPEC.BODY[4] := 'P';
- REPORT_FILE_SPEC.BODY[5] := '.';
- REPORT_FILE_SPEC.BODY[6] := 'R';
- REPORT_FILE_SPEC.BODY[7] := 'P';
- REPORT_FILE_SPEC.BODY[8] := 'T';
- REPORT_FILE_SPEC.LENGTH := 8;
-
- NR_SRC_FILES := 0;
-
- (* Default: *)
- EXTR_MODE := EMPTY_STRING_FIXED;
- AUX_STRING := 'OMITTED ';
- FOR I := 1 TO MAX_EXTR_MODE_L DO
- EXTR_MODE[I] := AUX_STRING[I];
-
- NR_MODULES:= 0;
- MODULE_DIRECTORY.BODY := EMPTY_STRING_FIXED;
- MODULE_DIRECTORY.LENGTH := 0;
-
- END (* WITH INIT_INFO *);
- (***************** End of INIT_RUN_INFO body ***********************)
- END (*INIT_RUN_INFO*);
-
- (*********************************************************************)
- (* Procedure: READ_INI_FILE *)
- (* Purpose: To open an initializationfile and read data from *)
- (* it into a record READ_INFO of type RUN_INFO_ . *)
- (* Interface: INI_FILE: The initializationfile in question. *)
- (* READ_INFO: Information for a run of CLIP. *)
- (* EXT_FILE_SPEC: The filespecification *)
- (* FILE_OK: TRUE if data read successfully *)
- (* ERROR_MSG: Error message. *)
- (* ERROR_CODE: Type of error. *)
- (* Author/date: Maarten Rooda, February 1991. *)
- (*********************************************************************)
- PROCEDURE READ_INI_FILE;
- VAR
- DUMMY_CODE: INTEGER;
-
- (*********************************************************************)
- (* Procedure: READ_INI_DATA *)
- (* Purpose: To read data from an initializationfile into a *)
- (* record READ_INFO of type RUN_INFO_ . *)
- (* Interface: INI_FILE - INI-file to be read *)
- (* READ_INFO - Structure to return the data. *)
- (* Author/date: Boudewijn Pelt, May 1991. *)
- (*********************************************************************)
- PROCEDURE READ_INI_DATA(VAR INI_FILE: TEXT;
- VAR READ_INFO: RUN_INFO_);
- CONST
- SKIP_LINES = 5;
- VAR
- COUNTER: INTEGER;
- LETTER: STRING_FIXED_; (* This is an array that can be read by *)
- (* READ_STRING *)
- DUMMY_L: INTEGER; (* A dummy parameter for READ_STRING *)
- OK: BOOLEAN;
- AUX_STR_34 : PACKED ARRAY[1..34] OF CHAR;
-
-
- (*********************************************************************)
- (* Routine: GET_SOURCE_FILES *)
- (* Purpose: To read a number of filespecifications from an *)
- (* input file. *)
- (* Interface: FILE_IN - File with data to be read *)
- (* FILES - Data of files *)
- (* NR_FILES - Number of files *)
- (* Author/date: Boudewijn Pelt, August 1991 *)
- (* Modified: Hans Rabouw, March 1992 *)
- (*********************************************************************)
- PROCEDURE GET_SOURCE_FILES
- (VAR FILE_IN: TEXT;
- VAR FILES: SOURCE_FILES_;
- VAR NR_FILES: INTEGER);
- VAR
- I: INTEGER;
- READ_ON: BOOLEAN;
- AUX_FILE_SPEC: FILE_SPEC_;
-
- BEGIN
- I := 0;
- READ_ON := NOT (EOF (FILE_IN));
- WHILE READ_ON DO
- BEGIN
- WITH AUX_FILE_SPEC DO
- READ_STRING(FILE_IN, LENGTH, BODY, MAX_FILE_SPEC_L);
- READ_LINE_SAFELY(INI_FILE);
- IF (AUX_FILE_SPEC.BODY[1] = '-') OR
- (AUX_FILE_SPEC.LENGTH = 0) THEN
- (* AUX_FILE_SPEC was not read successfully. *)
- READ_ON := FALSE
- ELSE IF I < MAX_NR_SRC_FILES THEN
- BEGIN
- (* AUX_FILE_SPEC was read successfully. *)
- I := I + 1;
- FILES[I] := AUX_FILE_SPEC;
- END (*IF.IF*);
- END (*WHILE*);
- NR_FILES := I;
- END (*GET_SOURCE_FILES*);
-
-
- (*********************************************************************)
- (* Routine: GET_MODULES *)
- (* Purpose: To read a number of filespecifications from an *)
- (* input file. *)
- (* Interface: FILE_IN - File with data to be read *)
- (* FILES - Data of files *)
- (* NR_FILES - Number of files *)
- (* Author/date: Boudewijn Pelt, August 1991 *)
- (* Modified: Hans Rabouw, March 1992 *)
- (*********************************************************************)
- PROCEDURE GET_MODULES
- (VAR FILE_IN: TEXT;
- VAR FILES: RSLT_MODULES_;
- VAR NR_FILES: INTEGER);
-
- VAR
- I: INTEGER;
- READ_ON: BOOLEAN;
- AUX_FILE_SPEC: FILE_SPEC_;
- AUX_PATH_SPEC: FILE_SPEC_;
-
- BEGIN
- I := 0;
- READ_ON := NOT (EOF (FILE_IN));
- WHILE READ_ON DO
- BEGIN
- WITH AUX_PATH_SPEC DO
- READ_STRING(FILE_IN, LENGTH, BODY, MAX_FILE_SPEC_L);
- READ_LINE_SAFELY(INI_FILE);
- IF (AUX_PATH_SPEC.BODY[1] = '-')
- (* OR (AUX_PATH_SPEC.LENGTH = 0) (EWvA nav. HR 17/11/92) *)
- THEN
- (* AUX_PATH_SPEC was not read successfully. *)
- READ_ON := FALSE
- ELSE
- BEGIN
- WITH AUX_FILE_SPEC DO
- READ_STRING(FILE_IN, LENGTH, BODY, MAX_FILE_SPEC_L);
- READ_LINE_SAFELY(INI_FILE);
- IF (AUX_FILE_SPEC.BODY[1] = '-') OR
- (AUX_FILE_SPEC.LENGTH = 0) THEN
- READ_ON := FALSE
- ELSE IF I < MAX_NR_RSLT_MODULES THEN
- BEGIN
- (* AUX_FILE_SPEC was read successfully. *)
- I := I + 1;
- FILES[I].FILE_NAME := AUX_FILE_SPEC;
- FILES[I].PATH := AUX_PATH_SPEC;
- END (*IF.IF*);
- END (*IF*);
- END (*WHILE*);
- NR_FILES := I;
- END (*GET_MODULES*);
-
-
- BEGIN
- (******* READ_INI_DATA body *******)
- RESET (INI_FILE);
- FOR COUNTER := 1 TO SKIP_LINES DO
- READ_LINE_SAFELY(INI_FILE);
- WITH READ_INFO DO
- BEGIN
- (********************* READ_INI_DATA (1) ***********************)
- (** Read the data from INI_FILE into MODE, INT_FAULT_CORR, **)
- (** MESSAGE_DESTINATION, REPORT_FILE_SPEC, CLIP_LPAR, CLIP_- **)
- (** RPAR, CLIP_CC, CLIP_END, OPTION_MARKER, NR_SCR_FILES, **)
- (** SOURCE_FILES, NR_MODULES, EXTR_MODE, RSLT_MODULES. **)
- READ_STRING(INI_FILE, DUMMY_L, MODE, MAX_MODE_L);
- READ_LINE_SAFELY(INI_FILE);
- READ_STRING(INI_FILE, DUMMY_L, LETTER, 1);
- READ_LINE_SAFELY(INI_FILE);
- INT_FAULT_CORR := LETTER[1] = 'Y';
- READ_STRING(INI_FILE, DUMMY_L, MESSAGE_DESTINATION, MAX_M_D_L);
- READ_LINE_SAFELY(INI_FILE);
- WITH CLIP_LPAR DO
- READ_STRING(INI_FILE, LENGTH, BODY, SYNTAX_LEN);
-
- READ_LINE_SAFELY(INI_FILE);
- WITH CLIP_RPAR DO
- READ_STRING(INI_FILE, LENGTH, BODY, SYNTAX_LEN);
-
- READ_LINE_SAFELY(INI_FILE);
- READ_STRING(INI_FILE, DUMMY_L, LETTER, 1);
- READ_LINE_SAFELY(INI_FILE);
- CLIP_CC := LETTER[1];
- WITH CLIP_END DO
- READ_STRING(INI_FILE, LENGTH, BODY, SYNTAX_LEN);
-
- READ_LINE_SAFELY(INI_FILE);
- READ_STRING(INI_FILE, DUMMY_L, LETTER, 1);
- READ_LINE_SAFELY(INI_FILE);
- OPTION_MARKER := LETTER[1];
- READ_STRING(INI_FILE, DUMMY_L, EXTR_MODE, MAX_EXTR_MODE_L);
-
- READ_LINE_SAFELY(INI_FILE);
-
- (************************ READ_INI_DATA (1.1) **********************)
- (** Read the file specifications REPORT_FILE_SPEC, **)
- (** SOURCE_FILES.FILES[1..NR_FILE_SPECS] **)
- (** RSLT_MODULES.FILES[1..NR_FILE_SPECS] from the INI_FILE. **)
- READ_LINE_SAFELY(INI_FILE); (* Skip -- REPORT FILE -- *)
- WITH REPORT_FILE_SPEC DO
- READ_STRING(INI_FILE, LENGTH, BODY, MAX_FILE_SPEC_L);
-
- READ_LINE_SAFELY(INI_FILE);
- READ_LINE_SAFELY(INI_FILE); (* skip -- INPUT FILES -- *)
- GET_SOURCE_FILES (INI_FILE, SOURCE_FILES, NR_SRC_FILES);
- GET_MODULES (INI_FILE, RSLT_MODULES, NR_MODULES);
-
- (* There is no need to skip the '--- MODULE DIRECTORY ---' line *)
- (* because it is read by the GET_MODULES procedure *)
-
- WITH MODULE_DIRECTORY DO
- READ_STRING(INI_FILE, LENGTH, BODY, MAX_FILE_SPEC_L);
-
- (***************** End of READ_INI_DATA (1.1) **********************)
-
- (************************ READ_INI_DATA (1.2) **********************)
- (** CLIP_LPAR and CLIP_RPAR are not complete. An CLIP_CC needs to **)
- (** be added. **)
- WITH CLIP_LPAR DO
- BEGIN
- IF LENGTH < SYNTAX_LEN THEN
- LENGTH := LENGTH + 1;
- BODY[LENGTH] := CLIP_CC;
- END (*WITH*);
- WITH CLIP_RPAR DO
- BEGIN
- LENGTH := LENGTH + 1;
- IF LENGTH > SYNTAX_LEN THEN
- LENGTH := SYNTAX_LEN;
- FOR COUNTER := LENGTH-1 DOWNTO 1 DO
- BODY[COUNTER+1] := BODY[COUNTER];
- BODY[1] := CLIP_CC;
- END (*WITH*);
- (****************** End of READ_INI_DATA (1.2) *********************)
-
- (***************** End of READ_INI_DATA (1) ********************)
- END (*WITH*);
-
- (************************* READ_INI_DATA (2) ***********************)
- (** Check if READ_INFO is valid. If not display an error message **)
- (** and set READ_INFO to default values. **)
- VAL_INI_DATA (READ_INFO, OK);
- IF NOT OK THEN
- BEGIN
- (********************* READ_INI_DATA (2.1) *********************)
- (** Generate a warning message **)
- ERROR_CODE := CORRUPT_INI_FILE;
- ERROR_MSG := EMPTY_STRING_FIXED;
- AUX_STR_34 := 'THE SPECIFIED INI-FILE IS CORRUPT.';
- FOR COUNTER := 1 TO 34 DO
- ERROR_MSG[COUNTER] := AUX_STR_34[COUNTER];
- (***************** End of READ_INI_DATA (2.1) ******************)
- INIT_RUN_INFO(READ_INFO);
- END (*IF*);
- (********************* End of READ_INI_DATA (2) ********************)
-
- (***************** End of READ_INI_DATA body ***********************)
- END (*READ_INI_DATA*);
-
- BEGIN
- FILE_OK := FALSE;
- EXT_FILE_PREP(INI_FILE, EXT_FILE_SPEC, INSP_MODE, FILE_OK,
- ERROR_CODE, ERROR_MSG);
- IF FILE_OK THEN
- BEGIN
- READ_INI_DATA (INI_FILE, READ_INFO);
- (* If the INI-file contained an error, the READ_INFO record *)
- (* was initialized by READ_INI_DATA. *)
- EXT_FILE_CLOSE (INI_FILE, DUMMY_CODE); (* EWvA, 16/10/93 *)
- END (*IF*);
- END (*READ_INI_FILE*);
-
- (*********************************************************************)
- (* Procedure: READ_STRING *)
- (* Purpose: read a string from a text file and determine its *)
- (* length. *)
- (* Interface: IN_FILE - File to be read *)
- (* IN_STR_LN - Index in line to be read *)
- (* IN_STR_BODY - Body of the line *)
- (* Author/date: Maarten Rooda, September 1990. *)
- (* Modified: Boudewijn Pelt, June 1991 & July 1991. *)
- (* Hans Rabouw, March 1992 *)
- (*********************************************************************)
- PROCEDURE READ_STRING;
- VAR
- INDEX: INTEGER;
-
- BEGIN
- (* File is already open and in inspection mode. *)
- (* A prompt, if needed, has already been issued. *)
- IN_STR_LN := 0;
- INDEX := 1;
- IF NOT (EOF(IN_FILE)) OR (EOLN (IN_FILE)) THEN
- BEGIN
- WHILE NOT (EOLN (IN_FILE) OR (INDEX > NR_CHARS_TO_READ)) DO
- BEGIN
- READ(IN_FILE, IN_STR_BODY[INDEX]);
- INDEX := INDEX + 1;
- END (*WHILE*);
- IN_STR_LN := INDEX - 1;
- IF IN_STR_LN > 0 THEN
- WHILE (IN_STR_BODY[IN_STR_LN] = ' ') AND
- (IN_STR_LN > 1) DO
- IN_STR_LN := IN_STR_LN - 1;
-
- (* If not all of the string has been filled, write spaces to *)
- (* the cells that have not been filled. *)
-
- FOR INDEX := INDEX TO STRING_FIXED_L DO
- IN_STR_BODY[INDEX] := ' ';
- END (*IF*);
- END (*READ_STRING*);
-
- (*********************************************************************)
- (* Routine: UC - convert character to Upper-Case *)
- (* Purpose: To transform lower case letters to their uppercase *)
- (* equivalent. *)
- (* Interface: INCHAR - Character to be converted. *)
- (* <RETURNS> - Converted character. *)
- (* Author/Date: Vamp project management, october 1983. *)
- (*********************************************************************)
- FUNCTION UC;
- BEGIN
- IF (INCHAR >= 'a') AND (INCHAR <= 'z') THEN
- UC := CHR (ORD(INCHAR) - ORD('a') + ORD('A'))
- ELSE
- UC := INCHAR;
- END (*UC*);
-
- (*********************************************************************)
- (* Routine: VAL_INI_DATA *)
- (* Purpose: Check if the run_info structure VAL_INFO is valid *)
- (* if this is not the case then attempt to fix it *)
- (* or return an error. (Make OK FALSE) *)
- (* Interface: VAL_INFO - Data from initialization. *)
- (* OK - TRUE if data OK. *)
- (* Author/date: Boudewijn Pelt, June 1991. *)
- (*********************************************************************)
- PROCEDURE VAL_INI_DATA;
- CONST
- AUX_STR_L = MAX_MODE_L;
-
- VAR
- ERROR: BOOLEAN;
- AUX_STRING: PACKED ARRAY [1..AUX_STR_L] OF CHAR;
- I: INTEGER;
-
- BEGIN
- ERROR := FALSE;
- WITH VAL_INFO DO
- BEGIN
- IF NOT (CHECK_SYNTAX(CLIP_LPAR, CLIP_RPAR, CLIP_END,
- CLIP_CC, OPTION_MARKER)) THEN
- ERROR := TRUE;
-
- (* Check MODE and set ERROR. *)
- IF MODE[1] IN ['I', 'i'] THEN
- AUX_STRING :='INTERACTIVE_MODE'
- ELSE IF MODE[1] IN ['A', 'a'] THEN
- AUX_STRING :='AUTO_MODE '
- ELSE IF MODE[1] IN ['H', 'h'] THEN
- AUX_STRING :='HELPFUL_MODE '
- ELSE IF MODE[1] IN ['D', 'd'] THEN
- AUX_STRING :='DEBUG_MODE '
- ELSE
- ERROR := TRUE;
-
- IF NOT ERROR THEN
- FOR I := 1 TO MAX_MODE_L DO
- MODE[I] := AUX_STRING[I];
-
- (* Check MESSAGE_DESTINATION and set ERROR. *)
- IF MESSAGE_DESTINATION[1] IN ['F', 'f'] THEN
- AUX_STRING := 'FILE '
- ELSE IF MESSAGE_DESTINATION[1] IN ['T', 't'] THEN
- AUX_STRING := 'TERMINAL '
- ELSE IF MESSAGE_DESTINATION[1] IN ['B', 'b'] THEN
- AUX_STRING := 'BOTH '
- ELSE IF MESSAGE_DESTINATION[1] IN ['N', 'n'] THEN
- AUX_STRING := 'NONE '
- ELSE
- ERROR := TRUE;
-
- IF NOT ERROR THEN
- FOR I := 1 TO MAX_M_D_L DO
- MESSAGE_DESTINATION[I] := AUX_STRING[I];
-
- (* Check EXTR_MODE and set ERROR. *)
- IF EXTR_MODE[1] IN ['E', 'e'] THEN
- AUX_STRING := 'EXTRACTED '
- ELSE IF EXTR_MODE[1] IN ['O', 'o'] THEN
- AUX_STRING := 'OMITTED '
- ELSE
- ERROR := TRUE;
-
- IF NOT ERROR THEN
- FOR I := 1 TO MAX_EXTR_MODE_L DO
- EXTR_MODE[I] := AUX_STRING[I];
-
- END (*WITH*);
- OK := NOT ERROR;
- END (*VAL_INI_DATA*);
-
- (*----------- File Table routines (ADT) --------------------------*)
-
- (*********************************************************************)
- (* Routine: FT_ABS_LINE_NUMBER - File Table ABSolute LINE NUMBER.*)
- (* Purpose: To return the absolute line number of a source line *)
- (* the source file. *)
- (* Interface: SOURCE_LINE - The specified source line. *)
- (* RETURNS - Absolute line number of the given *)
- (* SOURCE_LINE. *)
- (*********************************************************************)
- FUNCTION FT_ABS_LINE_NUMBER;
- BEGIN
- FT_ABS_LINE_NUMBER := SOURCE_LINE.ID;
- END (*FUNCTION FT_ABS_LINE_NUMBER*);
-
- (*********************************************************************)
- (* Routine: FT_CHECK_FILE *)
- (* Purpose: Checks whether a file is acccessable or not. *)
- (* Interface: FILE_SPEC - Specification of file to check. *)
- (* RETURNS - Code of a possible error. *)
- (* FT vars: CURR_IN_FILE. *)
- (*********************************************************************)
- FUNCTION FT_CHECK_FILE;
- VAR
- ERROR_CODE: ERROR_CODE_;
- DUMMY_FILE_OK: BOOLEAN;
- DUMMY_ERROR_MSG: ERROR_MSG_;
-
- BEGIN
- EXT_FILE_PREP (CURR_IN_FILE, FILE_SPEC, INSP_MODE, DUMMY_FILE_OK,
- ERROR_CODE, DUMMY_ERROR_MSG);
- IF ERROR_CODE<=0 THEN
- CLOSE (CURR_IN_FILE);
- FT_CHECK_FILE := ERROR_CODE;
- END (*FT_CHECK_FILE*);
-
- (*********************************************************************)
- (* Routine: FT_EOF *)
- (* Purpose: The function examines if the currently read file is *)
- (* exhausted. *)
- (* Interface: RETURNS - TRUE if the file is exhausted. *)
- (* FT vars: CURR_IN_FILE. *)
- (*********************************************************************)
- FUNCTION FT_EOF;
- BEGIN
- IF NOT EOF(CURR_IN_FILE) THEN
- FT_EOF := FALSE
- ELSE
- FT_EOF := TRUE;
- END (*FT_EOF*);
-
- (*********************************************************************)
- (* Routine: FT_GET_CHAR *)
- (* Purpose: To locate a character at a given position in a *)
- (* source_line and to return this character. *)
- (* Interface: SOURCE_LINE - The source line. *)
- (* INDEX - Index of the desired character. *)
- (* RETURNS - The desired character. *)
- (* CLIP objs: MAX_LINE. *)
- (*********************************************************************)
- FUNCTION FT_GET_CHAR;
- BEGIN
- IF (INDEX > MAX_LINE) OR (INDEX <= 0) THEN
- BEGIN
- WRITELN (OUTPUT, 'FT-GET-CHAR (a): ',
- 'System Failure... Call maintenance.');
- CLIP_STOP;
- END (*IF*);
- IF INDEX > SOURCE_LINE.USED THEN
- BEGIN
- WRITELN (OUTPUT, 'FT-GET-CHAR (B): ',
- 'System Failure... Call maintenance.');
- CLIP_STOP;
- END (*IF*);
-
- (* Index is within legal range. Proceed... *)
- FT_GET_CHAR := SOURCE_LINE.CHARS[INDEX];
- END (*FT_GET_CHAR*);
-
- (*********************************************************************)
- (* Routine: FT_GET_FILE_SPEC *)
- (* Purpose: To return the file specification of a source line *)
- (* Interface: SOURCE_LINE - The source line. *)
- (* FILE_SPEC - The wanted file specification. *)
- (* FT vars: FILE_TABLE. *)
- (*********************************************************************)
- PROCEDURE FT_GET_FILE_SPEC;
- VAR
- INDEX: FT_INDEX_;
-
- BEGIN
- (* Beware of non-existing line identifications. *)
- IF (SOURCE_LINE.ID <= 0) OR
- (SOURCE_LINE.ID > FILE_TABLE[LAST_FILE].LAST) THEN
- BEGIN
- WRITELN (OUTPUT, 'FT-GET-FILE-SPEC: ',
- 'System Failure... Call maintenance.');
- CLIP_STOP;
- END (*IF*);
-
- (* Line surely exist in FT. Find its specification. *)
- INDEX := 1;
- WHILE FILE_TABLE[INDEX].LAST < SOURCE_LINE.ID DO
- INDEX := INDEX+1;
- FILE_SPEC := FILE_TABLE[INDEX].FILE_SPEC;
- END (*FT_GET_FILE_SPEC*);
-
- (*********************************************************************)
- (* Routine: FT_GET_INDENT *)
- (* Purpose: To return the indentation of a line *)
- (* Interface: SOURCE_LINE - The source line. *)
- (* RETURNS - The indentation of SOURCE_LINE. *)
- (*********************************************************************)
- FUNCTION FT_GET_INDENT;
- BEGIN
- FT_GET_INDENT := SOURCE_LINE.INDENT;
- END (*FT_GET_INDENT*);
-
- (*********************************************************************)
- (* Routine: FT_GET_LINE_LENGTH *)
- (* Purpose: To return the length of a line *)
- (* Interface: SOURCE_LINE - Line-descriptor to be examined. *)
- (* RETURNS - Length of given line. *)
- (*********************************************************************)
- FUNCTION FT_GET_LINE_LENGTH;
- BEGIN
- FT_GET_LINE_LENGTH := SOURCE_LINE.USED;
- END (*FT_GET_LINE_LENGTH*);
-
- (*********************************************************************)
- (* Routine: FT_GET_LINE_NUMBER *)
- (* Purpose: To return the line number of a source line. *)
- (* Interface: SOURCE_LINE - The source line *)
- (* RETURNS - Line number or error code. *)
- (* FT vars: FILE_TABLE. *)
- (*********************************************************************)
- FUNCTION FT_GET_LINE_NUMBER;
- VAR
- INDEX: FT_INDEX_;
-
- BEGIN
- (* Beware of non-existing line identifications. *)
- IF (SOURCE_LINE.ID <= 0) OR
- (SOURCE_LINE.ID > FILE_TABLE[LAST_FILE].LAST) THEN
- BEGIN
- WRITELN (OUTPUT, 'FT_GET_LINE_NUMBER: ',
- 'System Failure... Call maintenance.');
- CLIP_STOP;
- END (*IF*);
-
- (* Line surely exist in FT. Find its number. *)
- INDEX := 1;
- WHILE FILE_TABLE[INDEX].LAST < SOURCE_LINE.ID DO
- INDEX := INDEX + 1;
- FT_GET_LINE_NUMBER := SOURCE_LINE.ID - FILE_TABLE[INDEX].FIRST + 1;
- END (*FT_GET_LINE_NUMBER*);
-
- (*********************************************************************)
- (* Routine: FT_GET_POS_OPTION_MARKER *)
- (* Purpose: Return the value of POS_OPTION_MARKER. *)
- (* Interface: SOURCE_LINE - Line-descriptor to be examined. *)
- (* RETURNS - Position of the OPTION_MARKER. *)
- (*********************************************************************)
- FUNCTION FT_GET_POS_OPTION_MARKER;
- BEGIN
- FT_GET_POS_OPTION_MARKER := SOURCE_LINE.POS_OPTION_MARKER;
- END (*FT_GET_POS_MARKER*);
-
- (*********************************************************************)
- (* Routine: FT_INCLOSE *)
- (* Purpose: Close the current input file. *)
- (* Interface: RETURNS - Code of a possible error. *)
- (* FT vars: CURR_IN_FILE. *)
- (*********************************************************************)
- FUNCTION FT_INCLOSE;
- VAR
- ERROR_CODE: ERROR_CODE_;
-
- BEGIN
- EXT_FILE_CLOSE (CURR_IN_FILE, ERROR_CODE);
- FT_INCLOSE := ERROR_CODE;
- END (*FT_INCLOSE*);
-
- (*********************************************************************)
- (* Routine: FT_INIT *)
- (* Purpose: General initialization of the file table. It is only *)
- (* activated once at the start of an run. *)
- (* FT vars: FILE_TABLE, LAST_LINE, LAST_FILE, SPACE. *)
- (*********************************************************************)
- PROCEDURE FT_INIT;
- VAR
- K: FT_INDEX_;
-
- BEGIN
- FOR K := 1 TO FT_SIZE DO
- WITH FILE_TABLE[K] DO
- BEGIN
- FILE_SPEC.LENGTH := 0;
- FIRST := 0;
- LAST := 0;
- END (*WITH*);
- LAST_LINE := 0;
- LAST_FILE := 0;
- SPACE := [CHR(0) .. CHR(9), CHR(14) .. CHR(25),
- CHR(28) .. CHR(32), CHR(11), CHR(127)];
- END (*FT_INIT*);
-
- (*********************************************************************)
- (* Routine: FT_INIT_LINE *)
- (* Purpose: Initialization of a LINE_DES_-object. *)
- (*********************************************************************)
- PROCEDURE FT_INIT_LINE;
- BEGIN
- WITH LINE DO
- BEGIN
- INDENT := 0;
- USED := 0;
- ID := 0;
- POS_OPTION_MARKER := 0;
- END (*WITH*);
- END (*FT_INIT_LINE*);
-
- (*********************************************************************)
- (* Routine: FT_INOPEN *)
- (* Purpose: Opens a new file with the given specification for *)
- (* read access. *)
- (* Interface: FILE_SPEC - Specification of file to open. *)
- (* RETURNS - Code of a possible error. *)
- (* FT vars: FILE_TABLE, LAST_FILE, CURR_IN_FILE. *)
- (*********************************************************************)
- FUNCTION FT_INOPEN;
- VAR
- ERROR_CODE: ERROR_CODE_;
- DUMMY_FILE_OK: BOOLEAN;
- DUMMY_ERROR_MSG: ERROR_MSG_;
-
- BEGIN
- EXT_FILE_PREP (CURR_IN_FILE, FILE_SPEC, INSP_MODE, DUMMY_FILE_OK,
- ERROR_CODE, DUMMY_ERROR_MSG);
- IF ERROR_CODE = 0 THEN
- BEGIN
- LAST_FILE := LAST_FILE+1;
- FILE_TABLE[LAST_FILE].FILE_SPEC := FILE_SPEC;
- END (*IF*);
- FT_INOPEN := ERROR_CODE;
- END (*FT_INOPEN*);
-
- (*********************************************************************)
- (* Routine: FT_OUTOPEN *)
- (* Purpose: Opens a new file with the given specification for *)
- (* write access. *)
- (* Interface: FILE_SPEC - Specification of outputfile. *)
- (* RETURNS - Code of a possible error. *)
- (* FT vars: CURR_OUT_FILE. *)
- (*********************************************************************)
- FUNCTION FT_OUTOPEN;
- VAR
- ERROR_CODE: ERROR_CODE_;
- DUMMY_FILE_OK: BOOLEAN;
- DUMMY_ERROR_MSG: ERROR_MSG_;
-
- BEGIN
- EXT_FILE_PREP (CURR_OUT_FILE, FILE_SPEC, GEN_MODE, DUMMY_FILE_OK,
- ERROR_CODE, DUMMY_ERROR_MSG);
-
- (* The opening was successfull. Make ERROR_CODE equal to *)
- (* STATUS (CURR_OUT_FILE) in case an error occured during the *)
- (* REWRITE operation (flagged by a value <> -1). *)
- FT_OUTOPEN := ERROR_CODE;
- END (*FT_OUTOPEN*);
-
- (*********************************************************************)
- (* Routine: FT_OUTCLOSE *)
- (* Purpose: Close the current output file. *)
- (* Interface: RETURNS - Code of a possible error. *)
- (* FT vars: CURR_OUT_FILE. *)
- (*********************************************************************)
- FUNCTION FT_OUTCLOSE;
- VAR
- ERROR_CODE: ERROR_CODE_;
-
- BEGIN
- EXT_FILE_CLOSE (CURR_OUT_FILE, ERROR_CODE);
- FT_OUTCLOSE := ERROR_CODE;
- END (*FT_OUTCLOSE*);
-
- (*********************************************************************)
- (* Routine: FT_RDLN *)
- (* Purpose: Read the next line from the current source-file. *)
- (* Interface: LINE - A source-line is returned in the form of a *)
- (* line descriptor. *)
- (* FT vars: SPACE *)
- (*********************************************************************)
- PROCEDURE FT_RDLN;
- CONST
- TAB = 8;
- VAR
- STR132: STRING132_;
- INDEX,
- K: INTEGER;
-
- BEGIN
- WITH LINE DO
- BEGIN
- INDENT := 0;
- USED := 0;
- POS_OPTION_MARKER := 0;
- WITH STR132 DO
- BEGIN
- BODY := EMPTY_STRING_FIXED;
- LENGTH := 0;
- WHILE (NOT EOLN(CURR_IN_FILE)) AND
- (LENGTH < STRING_FIXED_L) DO
- BEGIN
- LENGTH := LENGTH + 1;
- READ (CURR_IN_FILE, BODY[LENGTH]);
- END (*WHILE*);
- READLN (CURR_IN_FILE);
-
- (* Check spaces at beginning of string and calculate *)
- (* INDENT. *)
- INDEX := 1;
- WHILE (INDEX < LENGTH) AND (BODY[INDEX] IN SPACE) DO
- BEGIN
- IF BODY[INDEX] = CHR(9) THEN
- INDENT := INDENT + (TAB - (INDENT MOD TAB))
- ELSE
- INDENT := INDENT + 1;
- INDEX := INDEX + 1;
- END (*WHILE*);
-
- LAST_LINE := LAST_LINE + 1;
- FOR K := INDEX TO LENGTH DO
- CHARS[K-INDEX+1] := BODY[K];
-
- (* Remove spaces at the end of the line. *)
- IF LENGTH > 0 THEN
- BEGIN
- USED := LENGTH-INDEX+1;
- (*********************************************************************)
- (* Modified 14/10/93 by Mark Kramer to solve an index out of bound *)
- (* problem when bound checks are on. *)
- (* WHILE (USED >0) AND (CHARS[USED] IN SPACE) DO *)
- (* USED := USED-1; *)
-
- WHILE (USED > 1) AND (CHARS[USED] IN SPACE) DO
- USED := USED-1;
- IF (USED = 1) AND (CHARS[USED] IN SPACE) THEN
- USED := USED-1;
-
- (* End of modification 14/10/93. *)
- (*********************************************************************)
- END (*IF*);
- ID := LAST_LINE;
- END (*WITH*);
-
- (* Update the File Table. *)
- IF FILE_TABLE[LAST_FILE].FIRST = 0 THEN
- FILE_TABLE[LAST_FILE].FIRST := LAST_LINE;
- FILE_TABLE[LAST_FILE].LAST := LAST_LINE;
- END (*WITH*);
- END (*FT_RDLN*);
-
- (*********************************************************************)
- (* Routine: FT_WRLN *)
- (* Purpose: Write a line to the current output file. *)
- (* Interface: LINE - The line to be written. *)
- (* NR_BLANKS - The number of blanks leading the *)
- (* first character of LINE. *)
- (* DESTINATION - The destination of the line (screen, *)
- (* output file, reportfile etc.) *)
- (* REPORT_FILE - Report file for output. *)
- (*********************************************************************)
- PROCEDURE FT_WRLN;
- VAR
- INDEX: INTEGER;
- NR_TOTAL_BLANKS: INTEGER;
-
- BEGIN (*FT_WRLN*)
- NR_TOTAL_BLANKS := LINE.INDENT + NR_BLANKS;
- CASE DESTINATION OF
- 0: BEGIN
- FOR INDEX := 1 TO LINE.USED DO
- WRITE (OUTPUT, LINE.CHARS[INDEX]);
- WRITELN (OUTPUT);
- END;
- 1: BEGIN
- WRLN_STRING (CURR_OUT_FILE, LINE.CHARS, LINE.USED,
- NR_TOTAL_BLANKS);
- END;
- 2: BEGIN
- FOR INDEX := 1 TO LINE.USED DO
- WRITE (OUTPUT, LINE.CHARS[INDEX]);
- WRITELN (OUTPUT);
- END;
- 3: BEGIN
- WRLN_STRING (REPORT_FILE, LINE.CHARS, LINE.USED, 0);
- END;
- END (*CASE*);
-
- END (*FT_WRLN*);
-
- (*----------- Segment Table routines (ADT) -----------------------*)
-
- (*********************************************************************)
- (* Routine: ST_RD - Segment Table ReaD. *)
- (* Purpose: Read a line from the SEGMENT_TABLE. *)
- (* Interface: LINE - The line which is read. *)
- (* INDEX - The position of the line in SEGMENT_TABLE. *)
- (* ST vars: SEGMENT_TABLE. *)
- (*********************************************************************)
- PROCEDURE ST_RD (VAR LINE: LINE_DES_; INDEX: ST_INDEX_);
- BEGIN
-
- LINE := SEGMENT_TABLE.LINES[INDEX];
- END (*ST_READ*);
-
- (*********************************************************************)
- (* Routine: ST_WR - Segment Table WRite. *)
- (* Purpose: Write a line to the SEGMENT_TABLE. *)
- (* Interface: LINE - The line which is written *)
- (* INDEX- The position of the LINE. *)
- (* ST var: SEGMENT_TABLE. *)
- (*********************************************************************)
- PROCEDURE ST_WR (LINE: LINE_DES_; INDEX: ST_INDEX_);
- BEGIN
-
- SEGMENT_TABLE.LINES[INDEX] := LINE;
- END (*ST_WR*);
-
- (*********************************************************************)
- (* Routine: ST_ABS_SEG - Segment Table ABSolute SEGment *)
- (* Purpose: To return the absolute line number of the first *)
- (* line of the segment. *)
- (* Interface: SEGMENT - Given segment *)
- (* Function result - The absolute line number of the *)
- (* first line of SEGMENT. *)
- (* ST vars: SEGMENT_TABLE. *)
- (*********************************************************************)
- FUNCTION ST_ABS_SEG;
- VAR
- LINE: LINE_DES_;
-
- BEGIN
- IF SEGMENT.FIRST > 0 THEN
- BEGIN
- ST_RD (LINE, SEGMENT.FIRST);
- ST_ABS_SEG := FT_ABS_LINE_NUMBER (LINE);
- END (*IF*)
- END (*ST_ABS_SEG*);
-
- (*********************************************************************)
- (* Routine: ST_GET_FILE_SPEC *)
- (* Purpose: To return the file specification of the source file *)
- (* of the segment. *)
- (* Interface: SEGMENT - Given segment. *)
- (* FILE_SPEC - The file specification. *)
- (* ST vars: SEGMENT_TABLE. *)
- (*********************************************************************)
- PROCEDURE ST_GET_FILE_SPEC;
- VAR
- LINE: LINE_DES_;
-
- BEGIN
- ST_RD (LINE, SEGMENT.FIRST);
- FT_GET_FILE_SPEC (LINE, FILE_SPEC);
- END (*ST_GET_FILE_SPEC*);
-
- (*********************************************************************)
- (* Routine: ST_GET_INDENT *)
- (* Purpose: Return the indentation of segment. *)
- (* Interface: SEG - Segment to be investigated. *)
- (* RETURNS - Indent value or error-code. *)
- (*********************************************************************)
- FUNCTION ST_GET_INDENT;
- VAR
- LINE: LINE_DES_;
-
- BEGIN
- ST_RD (LINE, SEG.FIRST);
- ST_GET_INDENT := FT_GET_INDENT (LINE);
- END (*ST_GET_INDENT*);
-
- (*********************************************************************)
- (* Routine: ST_GET_LINE *)
- (* Purpose: Retrieves next line from the currently read segment. *)
- (* Interface: LINE - Returned line. *)
- (* ST vars: SEGMENT_TABLE, LAST_READ_SEG. *)
- (*********************************************************************)
- PROCEDURE ST_GET_LINE;
- VAR
- INDEX: ST_INDEX_;
-
- BEGIN
- WITH LAST_READ_SEG DO
- BEGIN
- IF ST_IS_EMPTY_SEG (LAST_SEG) THEN
- BEGIN
- (* ST_GET_LINE has not properly been prepared for reading.*)
- WRITELN (OUTPUT, 'ST-GET-LN: ',
- 'System Failure... Call maintenance.');
- CLIP_STOP;
- END
- ELSE
- BEGIN
- INDEX := LAST_LINE + 1;
- IF INDEX > LAST_SEG.LAST THEN
- BEGIN
- (* Segment exhausted. Return LINE with ID value 0. *)
- LINE.ID := 0;
- END
- ELSE
- BEGIN
- (* Retrieve line at position INDEX from the ST and *)
- (* update LAST_READ_SEG. *)
- ST_RD (LINE, INDEX);
- LAST_LINE := INDEX;
- END (*IF*);
- END (*IF*);
- END (*WITH*);
- END (*ST_GET_LINE*);
-
- (*********************************************************************)
- (* Routine: ST_GET_OPTION_LINE *)
- (* Purpose: To retrieve the first line from a segment which *)
- (* holds an option marker. *)
- (* Interface: SEG - The segment *)
- (* LINE - The first line holding an option marker *)
- (* ST vars: SEGMENT_TABLE, LAST_READ_SEG. *)
- (*********************************************************************)
- PROCEDURE ST_GET_OPTION_LINE;
- VAR
- INDEX: ST_INDEX_;
- POSITION: INTEGER;
- AUX_LINE: LINE_DES_;
-
- BEGIN
- INDEX := SEG.FIRST;
- POSITION := 0;
- IF INDEX > 0 THEN
- BEGIN
- WHILE (POSITION =0) AND (INDEX <= SEG.LAST) DO
- BEGIN
- ST_RD (AUX_LINE, INDEX);
- POSITION := FT_GET_POS_OPTION_MARKER (AUX_LINE);
- IF POSITION =0 THEN
- INDEX := INDEX + 1;
- END (*WHILE*);
- IF POSITION =0 THEN
- LINE.ID := 0
- ELSE
- LINE := AUX_LINE;
- WITH LAST_READ_SEG DO
- BEGIN
- LAST_SEG := SEG;
- LAST_LINE := INDEX;
- END (*WITH*);
- END
- ELSE
- BEGIN
- LAST_READ_SEG.LAST_SEG.FIRST := 0;
- LAST_READ_SEG.LAST_SEG.LAST := 0;
- LAST_READ_SEG.LAST_LINE := 0;
- LINE.ID := 0;
- END (*IF*);
- END (*ST_GET_OPTION_LINE*);
-
- (*********************************************************************)
- (* Routine: ST_GET_SEG *)
- (* Purpose: Retrieve the first line of a given segment from ST. *)
- (* Interface: LINE - Returned line. *)
- (* SEG - Segment to read from. *)
- (* ST vars: SEGMENT_TABLE, LAST_READ_SEG. *)
- (*********************************************************************)
- PROCEDURE ST_GET_SEG;
- BEGIN
- IF ST_IS_EMPTY_SEG (SEG) THEN
- BEGIN
- (* Return virtual line and reset LAST_READ_SEG. *)
- LINE.ID := 0;
- ST_INIT_SEG (LAST_READ_SEG.LAST_SEG);
- LAST_READ_SEG.LAST_LINE := 0;
- END
- ELSE
- BEGIN
- ST_RD (LINE, SEG.FIRST);
- WITH LAST_READ_SEG DO
- BEGIN
- LAST_SEG := SEG;
- LAST_LINE := SEG.FIRST;
- END (*WITH*);
- END (*IF*);
- END (*ST_GET_SEG*);
-
- (*********************************************************************)
- (* Routine: ST_GET_SEG_RANGE - Segment Table SEGMENT RANGE *)
- (* Purpose: To return the first and last relative line number of *)
- (* a segment. *)
- (* Interface: SEGMENT - Given segment. *)
- (* FIRST - The line number of the first segment line. *)
- (* LAST - The line number of the last segment line. *)
- (* ST vars: SEGMENT_TABLE. *)
- (*********************************************************************)
- PROCEDURE ST_GET_SEG_RANGE;
- VAR
- LINE: LINE_DES_;
-
- BEGIN
- FIRST := 0;
- LAST := 0;
- IF SEGMENT.FIRST > 0 THEN
- BEGIN
- ST_RD (LINE, SEGMENT.FIRST);
- FIRST := FT_GET_LINE_NUMBER (LINE);
- ST_RD (LINE, SEGMENT.LAST);
- LAST := FT_GET_LINE_NUMBER (LINE);
- END (*IF*);
- END (*ST_GET_SEG_RANGE*);
-
- (*********************************************************************)
- (* Routine: ST_INIT *)
- (* Purpose: General initialization of the segment table. To be *)
- (* invoked only once at the beginning of a run. *)
- (* ST vars: SEGMENT_TABLE, LAST_READ_SEG. *)
- (*********************************************************************)
- PROCEDURE ST_INIT;
- BEGIN
-
- SEGMENT_TABLE.USED := 0;
- ST_INIT_SEG (LAST_READ_SEG.LAST_SEG);
- LAST_READ_SEG.LAST_LINE := 0;
- END (*ST_INIT*);
-
- (*********************************************************************)
- (* Routine: ST_INIT_SEG *)
- (* Purpose: To establish a new and empty segment. *)
- (* Interface: SEG - the segment to initialize. *)
- (*********************************************************************)
- PROCEDURE ST_INIT_SEG;
- BEGIN
- SEG.FIRST := 0;
- SEG.LAST := -1;
- END (*ST_INIT_SEG*);
-
- (*********************************************************************)
- (* Routine: ST_IS_EMPTY_SEG *)
- (* Purpose: To examine if a segment is empty or not. *)
- (* Interface: SEG - Segment to be examined. *)
- (*********************************************************************)
- FUNCTION ST_IS_EMPTY_SEG;
- BEGIN
- ST_IS_EMPTY_SEG := (ST_NUMBER_OF_LINES (SEG) <= 0);
- END (*ST_IS_EMPTY_SEG*);
-
- (*********************************************************************)
- (* Routine: ST_NUMBER_OF_LINES *)
- (* Purpose: To calculate the number of lines in a segment. *)
- (* Interface: SEG - Segment to be investigated. *)
- (* RETURNS - Number of lines contained by segment. *)
- (*********************************************************************)
- FUNCTION ST_NUMBER_OF_LINES;
- BEGIN
- WITH SEG DO
- BEGIN
- IF (FIRST >= 0) AND (LAST >= FIRST -1) THEN
- BEGIN
- ST_NUMBER_OF_LINES := LAST - FIRST + 1;
- END
- ELSE
- BEGIN
- WRITELN (OUTPUT, 'ST-NUMBER-OF-LINES: ',
- 'System Failure... Call maintenance.');
- CLIP_STOP;
- END (*IF*);
- END (*WITH*);
- END (*ST_NUMBER_OF_LINES*);
-
- (*********************************************************************)
- (* Routine: ST_PUT_LINE *)
- (* Purpose: Add a source line to the last segment in the table. *)
- (* Interface: LINE - Source line to write. *)
- (* SEG - Segment to write to. *)
- (* ST vars: SEGMENT_TABLE. *)
- (*********************************************************************)
- PROCEDURE ST_PUT_LINE;
- BEGIN
- IF SEGMENT_TABLE.USED < ST_SIZE THEN
- BEGIN
- WITH SEGMENT_TABLE DO
- BEGIN
- (* Abort if the ST has become internally inconsistent. *)
- (* Othewise add line to the table. *)
- IF SEG.LAST <> USED THEN
- BEGIN
- WRITELN (OUTPUT, 'ST-PUT-LN: ',
- 'System Failure... Call maintenance.');
- CLIP_STOP;
- END
- ELSE
- BEGIN
- USED := USED + 1;
- ST_WR (LINE, USED);
- SEG.LAST := USED;
- END (*IF*)
- END (*WITH*);
- END
- ELSE
- BEGIN
- (* Segment Table to small for this application. *)
- WRITELN (OUTPUT, 'ST-PUT-LN: ',
- 'Parameter Failure... Call maintenance.');
- CLIP_STOP;
- END (*IF*);
- END (*ST_PUT_LINE*);
-
- (*********************************************************************)
- (* Routine: ST_PUT_SEG *)
- (* Purpose: Start a new segment in ST by writing its first line. *)
- (* Interface: LINE - The line to be written. *)
- (* SEG - The returned segment. *)
- (* ST vars: SEGMENT_TABLE, LAST_READ_SEG. *)
- (*********************************************************************)
- PROCEDURE ST_PUT_SEG;
- BEGIN
- IF SEGMENT_TABLE.USED < ST_SIZE THEN
- BEGIN
- WITH SEGMENT_TABLE DO
- BEGIN
- USED := USED + 1;
- ST_WR (LINE, USED);
- SEG.FIRST := USED;
- SEG.LAST := USED;
- END (*WITH*);
- END
- ELSE
- BEGIN
- WRITELN (OUTPUT, 'ST-PUT-SEG: ',
- 'Parameter Failure... Call maintenance.');
- CLIP_STOP;
- END (*IF*);
- END (*ST_PUT_SEG*);
-
- (*********************************************************************)
- (* Routine: ST_FINIT - FINIsh Segment Table *)
- (* Purpose: Remove the segment-file from the directory. *)
- (* Interface: - *)
- (* ST vars: SEGMENT_TABLE. *)
- (*********************************************************************)
- PROCEDURE ST_FINIT;
- BEGIN
- END (*ST_REMOVE*);
-
- (*********************************************************************)
- (* Routine: ST_SEG_WIDTH - Segment Table SEGment USED. *)
- (* Purpose: Return the horizontal length of a segment. *)
- (* Interface: SEGMENT - Given segment. *)
- (* RETURNS - Length of the given segment. *)
- (* ST vars: SEGMENT_TABLE. *)
- (*********************************************************************)
- FUNCTION ST_SEG_WIDTH;
- VAR
- LINE: LINE_DES_;
-
- BEGIN
- ST_RD (LINE, SEG.FIRST);
- ST_SEG_WIDTH := FT_GET_LINE_LENGTH (LINE);
- END;
-
- (*********************************************************************)
- (* Routine: ST_WRITE_SEG *)
- (* Purpose: To write a segment to an output file. *)
- (* Interface: SEG - Segment to be written. *)
- (* BLANKS - Leading blanks for every line of the *)
- (* segment. *)
- (* DESTINATION - Indicates the destination of the *)
- (* writing action. *)
- (* REPORT_FILE - Report file for output. *)
- (*********************************************************************)
- PROCEDURE ST_WRITE_SEG;
- VAR
- K: ST_INDEX_;
- LINE: LINE_DES_;
-
- BEGIN
- IF SEG.FIRST >0 THEN
- FOR K := SEG.FIRST TO SEG.LAST DO
- BEGIN
- ST_RD (LINE, K);
- FT_WRLN (LINE, BLANKS, DESTINATION);
- END (*FOR*);
- END (*ST_WRITE_SEG*);
-
- (*----------- String Pool routines (ADT) -------------------------*)
-
- (*********************************************************************)
- (* Routine: SP_ADD_CHAR *)
- (* Purpose: Add character to currently written string. *)
- (* Interface: CH - Character to be added. *)
- (* STR - String to add character to. *)
- (*********************************************************************)
- PROCEDURE SP_ADD_CHAR;
- BEGIN
- WITH STRING_POOL^ DO
- IF USED < SP_SIZE THEN
- BEGIN
- (* SP has enough space left to accept another character. *)
- USED := USED + 1;
- CHARS[USED] := CH;
- IF STR.FIRST =0 THEN
- BEGIN
- (* First character of a new string. *)
- STR.FIRST := USED;
- STR.LAST := USED;
- END
- ELSE
- BEGIN
- (* The string already exists. Abort if this string is *)
- (* not physically the last one of the SP. *)
- IF STR.LAST <> USED - 1 THEN
- BEGIN
- WRITELN (OUTPUT, 'SP-ADD-CHAR: ',
- 'System Failure... Call maintenance.');
- CLIP_STOP;
- END (*IF*);
- STR.LAST := USED;
- END (*IF*);
- END
- ELSE
- BEGIN
- WRITELN (OUTPUT, 'SP-ADD-CHAR: ',
- 'Parameter Failure... Call maintenance.');
- CLIP_STOP;
- END (*IF.WITH*);
- END (*SP_ADD_CHAR*);
-
- (*********************************************************************)
- (* Routine: SP_CONC_STR *)
- (* Purpose: Concatenation of neighbouring strings. *)
- (* Interface: MASTER - Recieving string. *)
- (* SLAVE - Concatented string *)
- (*********************************************************************)
- PROCEDURE SP_CONC_STR;
- BEGIN
- IF MASTER.FIRST =0 THEN
- (* An empty MASTER becomes a SLAVE... *)
- MASTER := SLAVE
- ELSE IF SLAVE.FIRST =0 THEN
- (* but an empty SLAVE does not bother its MASTER. *)
- (* DO NOTHING... *)
- ELSE IF MASTER.FIRST <>0 THEN
- BEGIN
- (* Concatenate only if SLAVE follows MASTER immediately. *)
- IF MASTER.LAST + 1 = SLAVE.FIRST THEN
- MASTER.LAST := SLAVE.LAST
- ELSE
- BEGIN
- WRITELN (OUTPUT, 'SP-CONC-STR: ',
- 'System Failure... Call maintenance.');
- CLIP_STOP;
- END (*IF*);
- END (*IF*);
- END (*SP_CONC_STR*);
-
- (*********************************************************************)
- (* Routine: SP_EQ *)
- (* Purpose: To decide if two strings are equal. *)
- (* Interface: STR1: First operand. *)
- (* STR2: Second operand. *)
- (* RETURNS: TRUE if both operands are equal. *)
- (* SP vars: STRING_POOL. *)
- (*********************************************************************)
- FUNCTION SP_EQ;
- VAR
- CONTINUE: BOOLEAN;
- INDEX: INTEGER;
- STR_L: INTEGER;
-
- BEGIN
- STR_L := SP_LENGTH_STR (STR1);
- IF STR_L <> SP_LENGTH_STR (STR2) THEN
- SP_EQ := FALSE
- ELSE
- BEGIN
- INDEX := 1;
- CONTINUE := TRUE;
- SP_EQ := TRUE;
- WHILE (CONTINUE) AND (INDEX <= STR_L) DO
- BEGIN
- IF SP_GET_CHAR (INDEX, STR1)
- <> SP_GET_CHAR (INDEX, STR2) THEN
- BEGIN
- CONTINUE := FALSE;
- SP_EQ := FALSE;
- END (*IF*);
- INDEX := INDEX + 1;
- END (*WHILE*);
- END (*IF*);
- END (*SP_EQ*);
-
- (*********************************************************************)
- (* Routine: SP_EXTR_STR *)
- (* Purpose: To extract a sequence of characters out of the SP *)
- (* and to store these characters in a packed array. *)
- (* Interface: STR - Descriptor of the wanted string. *)
- (* STR132 - The extracted characters. *)
- (*********************************************************************)
- PROCEDURE SP_EXTR_STR;
- VAR
- I: INTEGER;
- K: SP_INDEX_;
-
- BEGIN
- IF STR.FIRST= 0 THEN
- BEGIN
- STR132.LENGTH := 0;
- STR132.BODY := EMPTY_STRING_FIXED;
- END
- ELSE IF STR.LAST <= STRING_POOL^.USED THEN
- BEGIN
- STR132.BODY := EMPTY_STRING_FIXED;
- I := 0;
- FOR K := STR.FIRST TO STR.LAST DO
- BEGIN
- I := I + 1;
- STR132.BODY[I] := STRING_POOL^.CHARS[K];
- END;
- STR132.LENGTH := I;
- END
- ELSE
- BEGIN
- WRITELN (OUTPUT, 'SP_EXTR_STR: ',
- 'System Failure... Call maintenance.');
- CLIP_STOP;
- END (*IF.IF*);
- END;
-
- (*********************************************************************)
- (* Routine: SP_GET_CHAR *)
- (* Purpose: Get character from given position of a string. *)
- (* Interface: INDEX - Index of the wanted character. *)
- (* STR - String to be searched. *)
- (* RETURNS - Wanted character. *)
- (* SP vars: STRING_POOL. *)
- (* MOD1: EWvA (18/12/91) ivm probleem met SCAN_LINE (7). *)
- (*********************************************************************)
- FUNCTION SP_GET_CHAR;
- BEGIN
- WITH STR DO
- BEGIN
- (* Check if value of INDEX is within correct range. *)
- IF ((LAST - FIRST +1) < INDEX)
- OR (INDEX <= 0) THEN
- BEGIN
- (* MOD1: WRITELN (OUTPUT, 'SP-GET_CHAR: ', *)
- (* MOD1: 'System Failure... Call maintenance.'); *)
- (* MOD1: CLIP_STOP; *)
- SP_GET_CHAR := CHR(0); (* MOD1: *)
- END
- ELSE
- (* INDEX and STR are sound. Proceed to retrieve *)
- (* character. *)
- SP_GET_CHAR := STRING_POOL^.CHARS [FIRST + INDEX -1];
- END (*IF*)
- END (*SP_GET_CHAR*);
-
- (*********************************************************************)
- (* Routine: SP_INIT *)
- (* Purpose: General initialization of the String Pool. It is *)
- (* only activated once at the start of an CLIP-run. *)
- (*********************************************************************)
- PROCEDURE SP_INIT;
- BEGIN
- NEW (STRING_POOL);
- STRING_POOL^.USED := 0;
- END (*SP_INIT*);
-
- (*********************************************************************)
- (* Routine: SP_INIT_STR *)
- (* Purpose: Initialize a string *)
- (* Interface: STR - the string to be initialized. *)
- (*********************************************************************)
- PROCEDURE SP_INIT_STR;
- BEGIN
- STR.FIRST := 0;
- STR.LAST := -1;
- END (*SP_INIT_STR*);
-
- (*********************************************************************)
- (* Routine: SP_IS_EMPTY_STR *)
- (* Purpose: The function examines if a string is empty or not. *)
- (* Interface: STR - string to be examined. *)
- (* RETURNS - TRUE if string is empty. *)
- (*********************************************************************)
- FUNCTION SP_IS_EMPTY_STR;
- BEGIN
- SP_IS_EMPTY_STR := (SP_LENGTH_STR(STR) = 0);
- END (*SP_IS_EMPTY_STR*);
-
- (*********************************************************************)
- (* Routine: SP_LENGTH_STR *)
- (* Purpose: To calculate the length of a string. *)
- (* Interface: STR: Given string. *)
- (* RESULT: Length of STRING. *)
- (*********************************************************************)
- FUNCTION SP_LENGTH_STR;
- BEGIN
- SP_LENGTH_STR := STR.LAST - STR.FIRST + 1;
- END (*SP_LENGTH_STR*);
-
- (*********************************************************************)
- (* Routine: SP_ADD_BUFFER *)
- (* Purpose: Add the buffer to a string. *)
- (* Interface: STR - String to which the buffer is added. *)
- (* SP vars: BUFFER *)
- (*********************************************************************)
- PROCEDURE SP_ADD_BUFFER;
- VAR
- I : INTEGER;
-
- BEGIN
- SP_INIT_STR (STR);
- FOR I := 1 TO BUFFER.LENGTH DO
- SP_ADD_CHAR (BUFFER.BODY[I], STR);
- END (*SP_ADD_BUFFER*);
-
- (*********************************************************************)
- (* Routine: SP_ADD_BUFFER_CHAR *)
- (* Purpose: Add a character to the buffer. *)
- (* Interface: CH - Character to be added. *)
- (* SP vars: BUFFER *)
- (*********************************************************************)
- PROCEDURE SP_ADD_BUFFER_CHAR;
- BEGIN
- WITH BUFFER DO
- IF LENGTH < 132 THEN
- BEGIN
- LENGTH := LENGTH + 1;
- BODY[LENGTH] := CH;
- END
- ELSE
- BEGIN
- WRITELN (OUTPUT,'SP_ADD_BUFFER_CHAR system failure...',
- 'Call maintenance');
- CLIP_STOP;
- END (*IF*);
- END (*SP_ADD_BUFFER_CHAR*);
-
- (*********************************************************************)
- (* Routine: SP_GET_BUFFER_CHAR *)
- (* Purpose: Get a character from the buffer. *)
- (* Interface: INDEX - Index of the wanted character. *)
- (* SP_GET_BUFFER_CHAR - Character to get. *)
- (* SP vars: BUFFER *)
- (*********************************************************************)
- FUNCTION SP_GET_BUFFER_CHAR;
- BEGIN
- IF INDEX IN [1..BUFFER.LENGTH] THEN
- SP_GET_BUFFER_CHAR := BUFFER.BODY[INDEX]
- ELSE
- SP_GET_BUFFER_CHAR := CHR(0);
- END (*SP_GET_BUFFER_CHAR*);
-
- (*********************************************************************)
- (* Routine: SP_INIT_BUFFER *)
- (* Purpose: Initialize the buffer by making it empty. *)
- (* SP vars: BUFFER *)
- (*********************************************************************)
- PROCEDURE SP_INIT_BUFFER;
- BEGIN
- BUFFER.LENGTH := 0;
- END (*SP_INIT_BUFFER*);
-
- (*----------- DIAGNOSTic routines (ADT) --------------------------*)
-
- (*********************************************************************)
- (* Routine: DIAGNOST_INIT - INITialize the variables of DIAGNOST. *)
- (* Purpose: Initialize the global variables of procdure DIAG. *)
- (* Interface: - *)
- (* DIAGNOST vars: DIAG_TBL, NO_MESSAGES, NR_MSG. *)
- (*********************************************************************)
- PROCEDURE DIAGNOST_INIT;
-
- VAR
- K: INTEGER;
- TBL_FILE: TEXT;
- ERROR_CODE: INTEGER;
- DUMMY_ERROR: INTEGER;
- DUMMY_FILE_OK : BOOLEAN;
- DUMMY_ERROR_MSG : ERROR_MSG_;
- AUX_STRING_8: PACKED ARRAY[1..8] OF CHAR;
- TBL_FILE_NAME: FILE_SPEC_;
- MESS_CNT: INTEGER;
- CH : CHAR;
-
-
- BEGIN
- (******* DIAGNOST_INIT body *******)
- NO_MESSAGES := FALSE;
- NR_MSG := 0;
- FOR K := 1 TO MAX_NR_MESS DO
- DIAG_TBL[K].MESS_LOC := ' ';
-
- (* Clear the variable which is to hold the specification of the *)
- (* error message file. *)
- TBL_FILE_NAME.BODY := EMPTY_STRING_FIXED;
- TBL_FILE_NAME.LENGTH := 0;
-
- (******* DIAGNOST_INIT Add environment (TP) (#Opt) *******)
-
- (* Write name of message file to TBL_FLE_NAME. The length must *)
- (* be exactly 8 characters. *)
- AUX_STRING_8 := 'CLIP_MSG';
- WITH TBL_FILE_NAME DO
- BEGIN
- FOR K := 1 TO 8 DO
- BODY[LENGTH+K] := AUX_STRING_8[K];
- LENGTH := LENGTH + 8;
- END (* WITH *);
-
- (******* DIAGNOST_INIT Add extension (TP) (#Opt) *******)
-
- EXT_FILE_PREP (TBL_FILE, TBL_FILE_NAME, INSP_MODE, DUMMY_FILE_OK,
- ERROR_CODE, DUMMY_ERROR_MSG);
- IF ERROR_CODE <> 0 THEN
- BEGIN
- NO_MESSAGES := TRUE;
- WRITELN ('Error message file (logical name: CLIP_MSG) not found.');
- WRITELN ('CLiP will continue without diagnostics');
- WRITELN;
- END
- ELSE
- BEGIN
- NO_MESSAGES := FALSE;
-
- (********************* DIAGNOST_INIT (1) ***********************)
- (** Initialize DIAG_TBL by reading the TBL_FILE. **)
- MESS_CNT := 1;
- WHILE NOT EOF (TBL_FILE) DO
- BEGIN
- WITH DIAG_TBL[MESS_CNT] DO
- BEGIN
- (********************* DIAGNOST_INIT (1.1) *****************)
- (** Initialize DIAG_TBL[MESS_CNT].MESS_LOC. **)
- READ (TBL_FILE, CH);
- READ (TBL_FILE, CH);
- READ (TBL_FILE, CH);
- K := 1;
- WHILE CH <> ':' DO
- BEGIN
- MESS_LOC[K] := CH;
- READ (TBL_FILE, CH);
- K := K + 1;
- END (*WHILE*);
- (***************** End of DIAGNOST_INIT (1.1) **************)
-
- (********************* DIAGNOST_INIT (1.2) *****************)
- (** Initialize DIAG_TBL[MESS_CNT].MESSAGE. **)
- MESSAGE := EMPTY_STRING_FIXED;
- READ (TBL_FILE, CH);
- MESS_L := 1;
- WHILE CH <> '%' DO
- BEGIN
- IF EOLN (TBL_FILE) THEN
- READLN (TBL_FILE);
- READ (TBL_FILE, CH);
- IF CH <> '%' THEN
- BEGIN
- MESSAGE[MESS_L] := CH;
- MESS_L := MESS_L + 1;
- END (*IF*);
- END (*WHILE*);
- (***************** End of DIAGNOST_INIT (1.2) **************)
-
- READLN (TBL_FILE);
- END (*WITH*);
- MESS_CNT := MESS_CNT + 1;
- END (*WHILE*);
- (***************** End of DIAGNOST_INIT (1) ********************)
-
- (* Close the TBL_FILE and ignore any errors that may occur. *)
- EXT_FILE_CLOSE (TBL_FILE, DUMMY_ERROR);
- END (*IF*);
- (***************** End of DIAGNOST_INIT body *******************)
-
- END (*DIAGNOST_INIT*);
-
- (*********************************************************************)
- (* Routine: DIAG - Issue a DIAGnostic message. *)
- (* Purpose: Handling of all diagnostics by a message to the *)
- (* terminal. *)
- (* Interface: DIAG_TBL - Internal table with messages. *)
- (* MSG_TBL - Internal table with detected errors. *)
- (* NR_MSG - Counting error messages in MSG_TBL. *)
- (* SEV - Severity of the diagnostic. *)
- (* LOC - Program location which detected the *)
- (* problem. *)
- (* SOURCE_LINE - Source line causing the problem. *)
- (* SEGMENT - Segment causing the problem. *)
- (* STRING132 - Keyword(s) indicating the specific *)
- (* diagnostic. *)
- (*********************************************************************)
- PROCEDURE DIAG (SEV: SEV_CODE_;
- LOC: LOC_SPEC_;
- SOURCE_LINE: LINE_DES_;
- SEGMENT: SEGMENT_DES_;
- STRING132: STRING132_);
-
- VAR
- K : INTEGER;
-
- BEGIN
- (************************* DIAG (body) *****************************)
- IF NOT NO_MESSAGES THEN
- BEGIN
- IF NR_MSG < MAX_ERROR THEN
- BEGIN
- NR_MSG := NR_MSG + 1;
-
- (********************* DIAG (1) ************************)
- (** Store the actual parameters passed to DIAG in **)
- (** MSG_TBL[NR_MSG]. **)
- MSG_TBL[NR_MSG].SEV := SEV;
- MSG_TBL[NR_MSG].LOC := LOC;
- MSG_TBL[NR_MSG].STRING132 := STRING132;
- MSG_TBL[NR_MSG].SOURCE_LINE := SOURCE_LINE;
- MSG_TBL[NR_MSG].SEGMENT := SEGMENT;
- IF NOT ST_IS_EMPTY_SEG (SEGMENT) THEN
- MSG_TBL[NR_MSG].LINE_ABS := ST_ABS_SEG (SEGMENT)
- ELSE IF FT_GET_LINE_LENGTH (SOURCE_LINE) > 0 THEN
- MSG_TBL[NR_MSG].LINE_ABS :=
- FT_ABS_LINE_NUMBER (SOURCE_LINE)
- ELSE
- BEGIN
- WRITELN ('Internal error DIAG (1)... Call maintenance');
- WRITELN ('Troubles caused by an error detected by: ');
- FOR K := 1 TO LOC_SPEC_L DO
- WRITE (LOC[K]);
- NR_MSG := NR_MSG - 1;
- END (*IF.IF*);
- (******************* End of DIAG (1) *******************)
- END
- ELSE IF NR_MSG = MAX_ERROR THEN
- BEGIN
- WRITELN (OUTPUT, 'CLIP detected more then ',
- NR_MSG,' errors');
- WRITELN (OUTPUT, 'Only first ', NR_MSG,
- ' diagnostic messages will be generated');
- NR_MSG := NR_MSG + 1;
- END
- ELSE IF NR_MSG > MAX_ERROR THEN
- BEGIN
- (* Nothing remains to be done here. *)
- END (*IF.IF.IF*);
- END (*IF*);
- (********************* End of DIAG (body) **********************)
-
- END (*DIAG*);
-
- (*********************************************************************)
- (* Routine: DIAGNOST_EXIT - Exit the diagnostic table. *)
- (* Purpose: Generate the cumulated list of diagnostics to the *)
- (* termnal and, if specified, to a report file. *)
- (* Interface: DIAGNOST module variables *)
- (* REPORT_FILE - From CLIP_CDL *)
- (* REPORT_OK - From CLIP_CDL *)
- (* RUN_INFO variables *)
- (*********************************************************************)
- PROCEDURE DIAGNOST_EXIT;
-
- VAR
- I, K: INTEGER;
- MESS_INDEX: INTEGER;
- FILE_SPEC: FILE_SPEC_;
- FIRST, LAST: INTEGER;
- TMP_STRING_8: PACKED ARRAY [1..8] OF CHAR;
- J: INTEGER;
-
- BEGIN
- (********************* DIAGNOST_EXIT (body) ************************)
- IF NOT NO_MESSAGES THEN
- BEGIN
- IF NR_MSG > MAX_ERROR THEN
- NR_MSG := MAX_ERROR;
-
- (***************** DIAGNOST_EXIT (1) ***************************)
- (** Sort MSG_TBL by absolute line numbers. **)
- FOR K := NR_MSG DOWNTO 1 DO
- BEGIN
- FOR I := 1 TO K-1 DO
- BEGIN
- IF MSG_TBL[I].LINE_ABS > MSG_TBL[I+1].LINE_ABS THEN
- BEGIN
- MSG_TBL[MAX_ERROR+1] := MSG_TBL[I];
- MSG_TBL[I] := MSG_TBL[I+1];
- MSG_TBL[I+1] := MSG_TBL[MAX_ERROR+1];
- END (*IF*);
- END (*FOR*);
- END (*FOR*);
- (***************** End of DIAGNOST_EXIT (1) ********************)
-
- (* Write the opening lines of the report(s). *)
- IF NR_MSG > 0 THEN
- BEGIN
- WRITELN (OUTPUT, '============================ ',
- 'Diagnostics ===============================');
- IF REPORT_OK THEN
- WRITELN (REPORT_FILE, '============================ ',
- 'Diagnostics ===============================');
- END (* IF *);
-
- (***************** DIAGNOST_EXIT (2) ***************************)
- (** Generate messages from MSG_TBL and DIAG_TBL to OUTPUT and **)
- (** also to REPORT_FILE if REPORT_OK is raised. Write a **)
- (** diagnostic in case of trouble, but do not abort. **)
- FOR K := 1 TO NR_MSG DO
- BEGIN
- MESS_INDEX := 0;
-
- (***************** DIAGNOST_EXIT (2.1) *************************)
- (** Search DIAG_TBL for MSG_TBL[K].LOC. Store the index in **)
- (** MESS_INDEX. **)
- FOR I := 1 TO MAX_NR_MESS DO
- BEGIN
- IF DIAG_TBL[I].MESS_LOC = MSG_TBL[K].LOC THEN
- MESS_INDEX := I;
- END (*FOR*);
- (**************** End of DIAGNOST_EXIT (2.1) *******************)
-
- IF MESS_INDEX = 0 THEN
- BEGIN
- WRITELN (OUTPUT,
- 'system error DIAGNOST_EXIT ..... call maintenance');
- WRITELN ('Not able to generate diagnostic message.');
- WRITE ('DIAGNOST_EXIT was called by : ');
- FOR I := 1 TO LOC_SPEC_L DO
- WRITE (MSG_TBL[K].LOC[I]);
-
- IF REPORT_OK THEN
- BEGIN
- WRITELN (REPORT_FILE,
- 'system error DIAGNOST_EXIT ..... call maintenance');
- WRITELN (REPORT_FILE,
- 'Not able to generate diagnostic message.');
- WRITE (REPORT_FILE, 'DIAGNOST_EXIT was called by : ');
- FOR I := 1 TO LOC_SPEC_L DO
- WRITE (REPORT_FILE, MSG_TBL[K].LOC[I]);
- END (* IF *);
- END
- ELSE
- BEGIN
- (***************** DIAGNOST_EXIT (2.2) *********************)
- (** Generate diagnostic using information stored in MSG_- **)
- (** TBL[K] and DIAG_TBL[MESS_INDEX]. **)
- WITH MSG_TBL[K] DO
- BEGIN
- CASE SEV OF
- WARN:
- TMP_STRING_8 := 'Warning ';
- ERR:
- TMP_STRING_8 := 'Error ';
- FAIL:
- TMP_STRING_8 := 'Failure ';
- DUMP:
- CLIP_STOP;
- END (*CASE*);
- WRITE (OUTPUT, TMP_STRING_8);
- IF REPORT_OK THEN
- WRITE (REPORT_FILE, TMP_STRING_8);
-
- IF NOT ST_IS_EMPTY_SEG (SEGMENT) THEN
- BEGIN
- ST_GET_SEG_RANGE (SEGMENT, FIRST, LAST);
- ST_GET_FILE_SPEC (SEGMENT, FILE_SPEC);
- WRITE (' between the lines ', FIRST:2, ' and ',
- LAST:2, ' of file: ' );
- FOR I := 1 TO FILE_SPEC.LENGTH DO
- WRITE (FILE_SPEC.BODY[I]);
- WRITELN;
- WRITELN ('Source lines:');
- WRITELN;
-
- (* Write segement to OUTPUT. *)
- ST_WRITE_SEG (SEGMENT, 0, 0);
- WRITELN;
-
- IF REPORT_OK THEN
- BEGIN
- WRITE (REPORT_FILE, ' between the lines ', FIRST:2,
- ' and ', LAST:2, ' of file: ' );
- FOR I := 1 TO FILE_SPEC.LENGTH DO
- WRITE (REPORT_FILE, FILE_SPEC.BODY[I]);
- WRITELN (REPORT_FILE);
- WRITELN (REPORT_FILE, 'Source lines:');
- WRITELN (REPORT_FILE);
-
- (* Write segement to file variable REPORT_FILE of FT *)
- (* (see also DIAGNOST_EXIT (2)). *)
- ST_WRITE_SEG (SEGMENT, 0, 3);
- WRITELN (REPORT_FILE);
- END (* IF *);
- END
- ELSE IF FT_GET_LINE_LENGTH (SOURCE_LINE) > 0 THEN
- BEGIN
- FT_GET_FILE_SPEC (SOURCE_LINE, FILE_SPEC);
-
- WRITE ('in line ', FT_GET_LINE_NUMBER (SOURCE_LINE):4);
- WRITE (' of file :');
- FOR I := 1 TO FILE_SPEC.LENGTH DO
- WRITE (FILE_SPEC.BODY[I]);
- WRITELN;
-
- (* Write line to OUTPUT. *)
- FT_WRLN (SOURCE_LINE, 0, 0);
-
- IF REPORT_OK THEN
- BEGIN
- WRITE (REPORT_FILE, 'in line ',
- FT_GET_LINE_NUMBER (SOURCE_LINE):4);
- WRITE (REPORT_FILE, ' of file :');
- FOR I := 1 TO FILE_SPEC.LENGTH DO
- WRITE (REPORT_FILE, FILE_SPEC.BODY[I]);
- WRITELN (REPORT_FILE);
-
- (* Write LINE to file variable REPORT_FILE of FT *)
- (* (see also DIAGNOST_EXIT (2)). *)
- FT_WRLN (SOURCE_LINE, 0, 3);
- END (* IF *);
- END
- ELSE
- BEGIN
- WRITELN ('Internal error DIAG... Call maintenance');
- IF REPORT_OK THEN
- WRITELN (REPORT_FILE,
- 'Internal error DIAG... Call maintenance');
- END (*IF.IF*);
- WITH DIAG_TBL[MESS_INDEX] DO
- BEGIN
- FOR I := 1 TO MESS_L DO
- BEGIN
- IF MESSAGE[I] <> '@' THEN
- BEGIN
- WRITE (MESSAGE[I]);
- IF REPORT_OK THEN
- WRITE (REPORT_FILE, MESSAGE[I]);
- END
- ELSE
- BEGIN
- FOR J := 1 TO STRING132.LENGTH DO
- BEGIN
- WRITE (STRING132.BODY[J]);
- IF REPORT_OK THEN
- WRITE (REPORT_FILE, STRING132.BODY[J]);
- END (*FOR*);
- END (*IF*);
- END (*FOR*);
- END(*WITH*);
- END (*WITH*);
- (**************** End of DIAGNOST_EXIT (2.2) ***************)
- END (*IF*);
- WRITELN; WRITELN;
- WRITELN ('------------------------------------',
- '------------------------------------');
-
- IF REPORT_OK THEN
- BEGIN
- WRITELN (REPORT_FILE); WRITELN (REPORT_FILE);
- WRITELN (REPORT_FILE, '------------------------------------',
- '------------------------------------');
- END (* IF *);
- END (*FOR*);
- (**************** End of DIAGNOST_EXIT (2) *********************)
-
- (* Write closing remarks of the report(s). Don't forget to close *)
- (* the REPORT_FILE if it has been used. Ignore closing problems. *)
- IF NR_MSG > 0 THEN
- BEGIN
- WRITE (OUTPUT, 'Diagnostics TOTAL of: ',NR_MSG:1);
- IF REPORT_OK THEN
- WRITE (REPORT_FILE, 'Diagnostics TOTAL of: ',NR_MSG:1);
-
- (* Print different text to distinguish between a for single *)
- (* error situation and a multiple error situation. *)
- IF NR_MSG = 1 THEN
- BEGIN
- WRITELN (' error or warning detected.');
- IF REPORT_OK THEN
- WRITELN (REPORT_FILE, ' error or warning detected.');
- END
- ELSE
- BEGIN
- WRITELN (' errors or warnings detected.');
- IF REPORT_OK THEN
- WRITELN (REPORT_FILE, ' errors or warnings detected.');
- END (* IF *);
-
- WRITELN;
- WRITELN ('============================ End of ',
- 'diagnostics ========================');
- WRITELN;
- IF REPORT_OK THEN
- BEGIN
- WRITELN (REPORT_FILE);
- WRITELN (REPORT_FILE,
- '============================ End of ',
- 'diagnostics ========================');
- WRITELN (REPORT_FILE);
- END (* IF *);
- END (*IF*);
- END (*IF*);
- (**************** End of DIAGNOST_EXIT (body) **********************)
-
- END (*DIAG*);
-
-
- (*----------- Main components of the CLiP system -----------------*)
-
-
- (*********************************************************************)
- (* Routine: SCN_LINE_INIT - INITialize variables of SCN_LINE. *)
- (* Purpose: Initialize the global variables of procedure SCAN_LINE.*)
- (* Interface: - *)
- (* SCN_LINE vars: ALLOWED *)
- (*********************************************************************)
- PROCEDURE SCN_LINE_INIT;
- BEGIN
- ALLOWED := ['A'..'Z', 'a'..'z', '0'..'9','.'];
- END;
-
-
- (*********************************************************************)
- (* Routine: SCAN_LINE - Scan a source line *)
- (* Purpose: To examine to what sort of CLIP category a source *)
- (* line belongs to. *)
- (* Interface: SOURCE_LINE: The line to be scanned. *)
- (* LINE_INFO: A record structure that holding all *)
- (* relevant info of this SOURCE_LINE. *)
- (* RUN_INFO: General information for this run. *)
- (*********************************************************************)
- PROCEDURE SCAN_LINE (VAR LINE_INFO: LINE_INFO_;
- VAR SOURCE_LINE: LINE_DES_;
- RUN_INFO: RUN_INFO_);
-
- VAR
- SCAN_LINE_CONTINUE: BOOLEAN;
- L2_LINE,
- L3_LINE,
- L4_LINE: BOOLEAN;
- LENGTH_LINE: INTEGER;
- START_INDEX,
- END_INDEX: INTEGER;
- SEGMENT: SEGMENT_DES_;
- STRING132: STRING132_;
- OPEN_FOUND,
- CLOSE_FOUND: BOOLEAN;
- X, Y: INTEGER;
- CH: CHAR;
- CLIP_CCL: CHAR;
- CLIP_CCR: CHAR;
-
- BEGIN
- (******* SCAN_LINE (body) *******)
-
- (************************* SCAN_LINE (1) ***************************)
- (** Initialize the Buffer and SCAN_LINE_CONTINUE. **)
- SP_INIT_BUFFER;
- SCAN_LINE_CONTINUE := TRUE;
- (********************* End of SCAN_LINE (1) ************************)
-
- (************************* SCAN_LINE (2) ***************************)
- (** Examine the length of SOURCE_LINE. Make SCAN_LINE_CONTINUE to **)
- (** FALSE if this length is shorter then that of CLIP_LPAR and **)
- (** CLIP_RPAR together and set LINE_INFO.CATEGORY to L5. **)
- WITH RUN_INFO DO
- BEGIN
- LENGTH_LINE := FT_GET_LINE_LENGTH (SOURCE_LINE);
- IF LENGTH_LINE < CLIP_LPAR.LENGTH+CLIP_RPAR.LENGTH THEN
- BEGIN
- LINE_INFO.CATEGORY := L5;
- SCAN_LINE_CONTINUE := FALSE;
- END (*IF*);
- END (*WITH*);
- (********************* End of SCAN_LINE (2) ************************)
-
- IF SCAN_LINE_CONTINUE THEN
- BEGIN
- (************************* SCAN_LINE (3) ***********************)
- (** Examine if SOURCE_LINE starts with an CLIP_LPAR and ends **)
- (** with an CLIP_RPAR. Set SCAN_LINE_CONTINUE to FALSE if this **)
- (** is not the case. Generate error message using SOURCE_LINE **)
- (** if only one of the two strings is detected. **)
- X := 1;
- OPEN_FOUND := TRUE;
- WITH RUN_INFO DO
- BEGIN
- WHILE (X <= CLIP_LPAR.LENGTH) AND (SCAN_LINE_CONTINUE) DO
- BEGIN
- CH := FT_GET_CHAR (SOURCE_LINE, X);
- IF CLIP_LPAR.BODY[X] <> CH THEN
- BEGIN
- SCAN_LINE_CONTINUE := FALSE;
- OPEN_FOUND := FALSE;
- END (*IF*);
- X := X+1;
- END (*WHILE*);
-
- X := LENGTH_LINE-CLIP_RPAR.LENGTH+1;
- Y := 1;
- CLOSE_FOUND := TRUE;
- WHILE (X <=LENGTH_LINE) DO
- BEGIN
- CH := FT_GET_CHAR (SOURCE_LINE, X);
- IF CLIP_RPAR.BODY[Y] <> CH THEN
- BEGIN
- CLOSE_FOUND := FALSE;
- SCAN_LINE_CONTINUE := FALSE;
- END (*IF*);
- X := X+1;
- Y := Y+1;
- END (*WHILE*);
- END (*WITH*);
-
- IF NOT SCAN_LINE_CONTINUE THEN
- BEGIN
- ST_INIT_SEG (SEGMENT);
- STRING132.LENGTH := 0;
- STRING132.BODY := EMPTY_STRING_FIXED;
- IF (OPEN_FOUND) AND (NOT CLOSE_FOUND) THEN
- DIAG (WARN, 'SCAN_LINE (3a) ', SOURCE_LINE, SEGMENT,
- STRING132)
- ELSE IF (CLOSE_FOUND) AND (NOT OPEN_FOUND) THEN
- DIAG (WARN, 'SCAN_LINE (3b) ', SOURCE_LINE, SEGMENT,
- STRING132);
- END (*WITH*);
- (********************* End of SCAN_LINE (3) ********************)
-
- IF NOT SCAN_LINE_CONTINUE THEN
- LINE_INFO.CATEGORY := L5
- ELSE
- BEGIN
- L3_LINE := FALSE;
-
- (********************* SCAN_LINE (4) ***********************)
- (** Examine the character following CLIP_LPAR and the one **)
- (** preceeding CLIP_RPAR. Set L3_LINE to TRUE if at least **)
- (** one of these characters differs from CLIP_CC. Generate **)
- (** an error message using SOURCE_LINE if only one CLIP_CC **)
- (** is detected. **)
- WITH RUN_INFO DO
- BEGIN
- X := CLIP_LPAR.LENGTH+1;
- Y := LENGTH_LINE-CLIP_RPAR.LENGTH;
- CLIP_CCL := FT_GET_CHAR (SOURCE_LINE, X);
- CLIP_CCR := FT_GET_CHAR (SOURCE_LINE, Y);
-
- IF (CLIP_CCL <> CLIP_CC) AND (CLIP_CCR <> CLIP_CC) THEN
- BEGIN
- SCAN_LINE_CONTINUE := FALSE;
- L3_LINE := TRUE;
- END
- ELSE IF (CLIP_CCL<>CLIP_CC) AND (CLIP_CCR=CLIP_CC) THEN
- BEGIN
- ST_INIT_SEG (SEGMENT);
- STRING132.LENGTH := 0;
- STRING132.BODY := EMPTY_STRING_FIXED;
- DIAG (WARN, 'SCAN_LINE (4a) ', SOURCE_LINE, SEGMENT,
- STRING132);
- SCAN_LINE_CONTINUE := FALSE;
- L3_LINE := TRUE;
- END
- ELSE IF (CLIP_CCL = CLIP_CC) AND (CLIP_CCR <> CLIP_CC) THEN
- BEGIN
- ST_INIT_SEG (SEGMENT);
- STRING132.LENGTH := 0;
- STRING132.BODY := EMPTY_STRING_FIXED;
- DIAG (WARN, 'SCAN_LINE (4b) ', SOURCE_LINE, SEGMENT,
- STRING132);
- SCAN_LINE_CONTINUE := FALSE;
- L3_LINE := TRUE;
- END (*IF.IF.IF*);
- END (*WITH*);
- (***************** End of SCAN_LINE (4) ********************)
-
- IF (L3_LINE) AND (LINE_INFO.OPTIONS) THEN
- BEGIN
- (* SOURCE_LINE holds only options which will be *)
- (* scanned in a later stadium. Nothing remains to *)
- (* be done here. *)
- END
- ELSE
- BEGIN
- WITH RUN_INFO DO
- BEGIN
- START_INDEX := CLIP_LPAR.LENGTH;
- END_INDEX :=
- SOURCE_LINE.USED-RUN_INFO.CLIP_RPAR.LENGTH;
- END (*WITH*);
- L4_LINE := TRUE;
-
- (********************* SCAN_LINE (5) *******************)
- (** Examine the characters in SOURCE_LINE starting at **)
- (** START_INDEX until a character not equal to CLIP_CC **)
- (** or until END_INDEX is reached. If such a character **)
- (** is detected, set L4_LINE to FALSE and store its **)
- (** position in START_INDEX. **)
- WHILE (START_INDEX < END_INDEX) AND (L4_LINE) DO
- BEGIN
- CH := FT_GET_CHAR (SOURCE_LINE, START_INDEX);
- IF CH <> RUN_INFO.CLIP_CC THEN
- L4_LINE := FALSE
- ELSE
- START_INDEX := START_INDEX+1;
- END (*WHILE*);
- (***************** End of SCAN_LINE (5) ****************)
-
- IF NOT L4_LINE THEN
- BEGIN
- IF NOT L3_LINE THEN
- LINE_INFO.OPTIONS := FALSE;
- X := START_INDEX;
- WHILE (X <= END_INDEX) AND (NOT LINE_INFO.OPTIONS) DO
- BEGIN
- CH := FT_GET_CHAR (SOURCE_LINE, X);
- IF (CH IN ALLOWED) OR
- (CH=RUN_INFO.OPTION_MARKER) THEN
- BEGIN
- IF CH=RUN_INFO.OPTION_MARKER THEN
- BEGIN
- LINE_INFO.OPTIONS := TRUE;
- SOURCE_LINE.POS_OPTION_MARKER := X;
- END
- ELSE
- BEGIN
- (************* SCAN_LINE (6) ***********)
- (** Add CH to the Buffer String. **)
- SP_ADD_BUFFER_CHAR (UC (CH));
- (********* End of SCAN_LINE (6) ********)
- END (*IF*);
- END (*IF*);
- X := X+1;
- END (*WHILE*);
- L2_LINE := TRUE;
-
- (***************** SCAN_LINE (7) *******************)
- (** Check if the first LENGTH (CLIP_END) chars of **)
- (** the Bufffer String are equal to CLIP_END. If **)
- (** not, set L2_LINE to FALSE. **)
- WITH RUN_INFO DO
- BEGIN
- X := 1;
- WHILE (X <= CLIP_END.LENGTH) AND (SCAN_LINE_CONTINUE) DO
- BEGIN
- CH := SP_GET_BUFFER_CHAR (X);
- IF UC (CLIP_END.BODY[X]) <> UC (CH) THEN
- L2_LINE := FALSE;
- X := X+1;
- END (*WHILE*);
- END (*WITH*);
- (*************** End of SCAN_LINE (7) **************)
- END (*IF*);
- END (*IF*);
- IF L4_LINE THEN
- LINE_INFO.CATEGORY := L4
- ELSE IF L3_LINE THEN
- LINE_INFO.CATEGORY := L3
- ELSE IF L2_LINE THEN
- LINE_INFO.CATEGORY := L2
- ELSE
- LINE_INFO.CATEGORY := L1;
- END (*IF*);
- END (*IF*);
- (********************* End of SCAN_LINE (body) *****************)
- END (*PROCEDURE SCAN_LINE*);
-
-
- (********************************************************************)
- (* Routine: CONVERT_OPTION *)
- (* Purpose: Covert an abbreviated option to its full length. *)
- (* Interface: OPTION: Option to be converted. *)
- (* ERROR_CODE: 0 - No Problems. *)
- (* 1 - No Match found. *)
- (* -1 - More then one match found. *)
- (********************************************************************)
- PROCEDURE CONVERT_OPTION (VAR OPTION: OPTION_KEYWORD_;
- VAR ERROR_CODE: ERROR_CODE_);
-
- VAR
- K, I: INTEGER;
- LENGTH_OPTION: INTEGER;
- LOCATED: BOOLEAN;
- DUMMY: OPTION_KEYWORD_;
- NR_MATCH: INTEGER;
-
- BEGIN
- DUMMY := EMPTY_OPTION;
- K := 1;
- NR_MATCH := 0;
- WHILE OPTION[K] <> ' ' DO
- K := K + 1;
- LENGTH_OPTION := K-1;
- LOCATED := FALSE;
- I := 1;
- ERROR_CODE := 1; (* Assume no match found. *)
- WHILE (I <= MAX_OPTIONS) DO
- BEGIN
- K := 1;
- LOCATED := TRUE;
- WHILE (K <= LENGTH_OPTION) AND (LOCATED) DO
- BEGIN
- IF UC (OPTION[K]) = UC (OPTION_TABLE[I,K]) THEN
- LOCATED := TRUE
- ELSE
- LOCATED := FALSE;
- K := K + 1;
- END (*WHILE*);
-
- IF LOCATED THEN
- BEGIN
- IF NR_MATCH = 0 THEN
- BEGIN
- ERROR_CODE := 0; (* One match has been found. *)
- DUMMY := OPTION_TABLE[I];
- NR_MATCH := NR_MATCH + 1;
- END
- ELSE
- ERROR_CODE := -1; (* More then one match found *)
- END (*IF*);
- I := I + 1;
- END (*WHILE*);
- IF ERROR_CODE = 0 THEN
- OPTION := DUMMY;
- END (*CONVERT_OPTION*);
-
-
- (*********************************************************************)
- (* Routine: SCN_OPTS_INIT - INITialize the variables of SCN_OPTS. *)
- (* Purpose: Initialize the global variables of SCAN_OPTIONS. *)
- (* Interface: - *)
- (* SCN_OPTS vars: OPT_SPACE, DEFAULT_OPTIONS, OPT_CHARS, *)
- (* PASCAL_STRING, C_STRING. *)
- (*********************************************************************)
- PROCEDURE SCN_OPTS_INIT;
- BEGIN
- OPTION_TABLE [ 1] := 'QUICK ';
- OPTION_TABLE [ 2] := 'MULTIPLE ';
- OPTION_TABLE [ 3] := 'OPTIONAL ';
- OPTION_TABLE [ 4] := 'FILE ';
- OPTION_TABLE [ 5] := 'INDENT ';
- OPTION_TABLE [ 6] := 'COMMENT ';
- OPTION_TABLE [ 7] := 'OVERRULE ';
- OPTION_TABLE [ 8] := 'LEADER ';
- OPTION_TABLE [ 9] := 'TRAILER ';
- OPTION_TABLE [10] := 'SEPARATOR ';
- OPTION_TABLE [11] := 'DEFAULT ';
- OPTION_TABLE [12] := 'LINENUMBER ';
-
- OPT_CHARS := ['A'..'Z', 'a'..'z', '0'..'9', '"'];
-
- WITH DEFAULT_OPTIONS DO
- BEGIN
- QUICK := FALSE;
- MULTIPLE := FALSE;
- OPTIONAL := FALSE;
- OVERRULE := FALSE;
- LEADER := FALSE;
- DEFAULT := FALSE;
- TRAILER := FALSE;
- SEPARATOR := FALSE;
- LINENUMBER := FALSE;
- SP_INIT_STR (FILE_NAME);
- SP_INIT_STR (INDENT);
- SP_INIT_STR (COMMENT);
- END;
-
- PASCAL_STRING := EMPTY_STRING_FIXED;
- PASCAL_STRING[1] := 'P';
- PASCAL_STRING[2] := 'A';
- PASCAL_STRING[3] := 'S';
- PASCAL_STRING[4] := 'C';
- PASCAL_STRING[5] := 'A';
- PASCAL_STRING[6] := 'L';
-
- FORTRAN_STRING := EMPTY_STRING_FIXED;
- FORTRAN_STRING[1] := 'F';
- FORTRAN_STRING[2] := 'O';
- FORTRAN_STRING[3] := 'R';
- FORTRAN_STRING[4] := 'T';
- FORTRAN_STRING[5] := 'R';
- FORTRAN_STRING[6] := 'A';
- FORTRAN_STRING[7] := 'N';
-
- C_STRING := EMPTY_STRING_FIXED;
- C_STRING[1] := 'C';
-
- END;
-
-
- (*********************************************************************)
- (* Routine: SCAN_OPTIONS - SCAN OPTIONS *)
- (* Purpose: To scan and store the options that are specified by *)
- (* a stub or slot segment. *)
- (* Interface: SEGMENT_OPTIONS - The structure with options. *)
- (* SEGMENT - The segment to be scanned. *)
- (* RUN_INFO - The information for this run. *)
- (* SEGMENT_TYPE - Type of segment to be scanned. *)
- (*********************************************************************)
- PROCEDURE SCAN_OPTIONS (VAR SEGMENT_OPTIONS: OPTIONS_;
- SEGMENT: SEGMENT_DES_;
- RUN_INFO: RUN_INFO_;
- SEGMENT_TYPE: SEGMENT_TYPE_);
-
- VAR
- OPTION_KEYWORD: OPTION_KEYWORD_;
- LINE: LINE_DES_;
- SEGMENT_EXHAUSTED: BOOLEAN;
- INDEX: INTEGER;
- CH: CHAR;
- LENGTH_LINE: INTEGER;
- OK: BOOLEAN;
- STRING132: STRING132_;
- I: INTEGER;
- ERROR_CODE: ERROR_CODE_;
- DUMMY_LINE: LINE_DES_;
- AUX_STRING10: PACKED ARRAY[1..10] OF CHAR;
-
- BEGIN
- (******* SCAN_OPTIONS (body) *******)
-
- (************************* SCAN_OPTIONS (1) ********************)
- (** Initialize OPTION_KEYWORD. Make SEGMENT_OPTIONS equal to **)
- (** DEFAULT_OPTIONS and set SEGMENT_EXHAUSTED to FALSE. **)
- OPTION_KEYWORD := EMPTY_OPTION;
- SEGMENT_OPTIONS := DEFAULT_OPTIONS;
- SEGMENT_EXHAUSTED := FALSE;
- (********************* End of SCAN_OPTIONS (1) *****************)
-
- IF NOT ST_IS_EMPTY_SEG (SEGMENT) THEN
- BEGIN
- (********************* SCAN_OPTIONS (2) ********************)
- (** Retrieve first line from SEGMENT which holds an option **)
- (** marker and store it in LINE. Set SEGMENT_EXHAUSTED to **)
- (** TRUE if no such LINE could be found. **)
- ST_GET_OPTION_LINE (SEGMENT, LINE);
- IF LINE.ID =0 THEN
- SEGMENT_EXHAUSTED := TRUE;
- (***************** End of SCAN_OPTIONS (2) *****************)
-
- WHILE NOT SEGMENT_EXHAUSTED DO
- BEGIN
- (********************* SCAN_OPTIONS (3) ****************)
- (** Scan LINE for options with their arguments and put **)
- (** the result in SEGMENT_OPTIONS. Generate diagnostic **)
- (** message using SEGMENT in case of trouble. **)
- INDEX := FT_GET_POS_OPTION_MARKER (LINE);
- IF INDEX = 0 THEN
- INDEX := RUN_INFO.CLIP_LPAR.LENGTH + 1;
- LENGTH_LINE := FT_GET_LINE_LENGTH (LINE) - RUN_INFO.CLIP_RPAR.LENGTH;
- CH := FT_GET_CHAR (LINE, INDEX);
- WHILE INDEX < LENGTH_LINE DO
- BEGIN
- WHILE (CH <> RUN_INFO.OPTION_MARKER) AND
- (NOT (CH IN OPT_CHARS)) AND
- (INDEX < LENGTH_LINE) DO
- BEGIN
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END (*WHILE*);
-
- IF CH = RUN_INFO.OPTION_MARKER THEN
- BEGIN
- (********************* SCAN_OPTIONS (3.1) ******************)
- (** Start of a new option in LINE. Check by an empty **)
- (** OPTION_KEYWORD if previous option is "closed" correctly **)
- (** and issue a diagnostic if not. Read the characters **)
- (** following OPTION_MARKER until the next OPT_SPACE and **)
- (** store them in OPTION_KEYWORD. Read a possible argument **)
- (** and update SEGMENT_OPTIONS. Initialize OPTION_KEYWORD **)
- (** if all went well. **)
- IF OPTION_KEYWORD <> EMPTY_OPTION THEN
- BEGIN
- (********************* SCAN_OPTIONS (3.1.1) ********************)
- (** Missing argument of option stored in OPTION_KEYWORD. **)
- (** Generate a diagnostic using OPTION_KEYWORD and SEGMENT. **)
- STRING132.LENGTH := 0;
- STRING132.BODY := EMPTY_STRING_FIXED;
- FOR I := 1 TO MAX_OPTION_LENGTH DO
- BEGIN
- IF OPTION_KEYWORD[I] <> ' ' THEN
- BEGIN
- STRING132.BODY[I] := OPTION_KEYWORD[I];
- STRING132.LENGTH := STRING132.LENGTH + 1;
- END (*IF*);
- END (*FOR*);
- DIAG (ERR, 'SCAN_OPTIONS (3.1.1) ', DUMMY_LINE, SEGMENT, STRING132);
- OPTION_KEYWORD := EMPTY_OPTION;
- (***************** End of SCAN_OPTIONS (3.1.1) *****************)
- END (*IF*);
- OK := FALSE;
-
- (********************* SCAN_OPTIONS (3.1.2) ************************)
- (** Store all characters following this OPTION_MARKER in OPTION_- **)
- (** KEYWORD until the first character that is not a member of **)
- (** OPT_CHARS. Try to located the option in OPTION_TABLE and make **)
- (** OK equal to TRUE if a match is found and store the full option **)
- (** in OPTION_KEYWORD. In case no match can be found generate a **)
- (** diagnostic message and jump to the next option marker. **)
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- WHILE NOT (CH IN OPT_CHARS) AND
- (CH <> RUN_INFO.OPTION_MARKER) AND
- (INDEX < LENGTH_LINE) DO
- BEGIN
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END (*WHILE*);
- I := 1;
- WHILE CH IN OPT_CHARS DO
- BEGIN
- OPTION_KEYWORD [I] := CH;
- I := I + 1;
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END (*WHILE*);
- CONVERT_OPTION (OPTION_KEYWORD, ERROR_CODE);
- IF ERROR_CODE <> 0 THEN
- BEGIN
- STRING132.LENGTH := 0;
- STRING132.BODY := EMPTY_STRING_FIXED;
- FOR I := 1 TO MAX_OPTION_LENGTH DO
- BEGIN
- IF OPTION_KEYWORD[I] <> ' ' THEN
- BEGIN
- STRING132.BODY[I] := OPTION_KEYWORD[I];
- STRING132.LENGTH := STRING132.LENGTH + 1;
- END (*IF*);
- END (*FOR*);
- IF ERROR_CODE = -1 THEN
- BEGIN
- (* More then one match found in table. *)
- DIAG (ERR, 'SCAN_OPTIONS (3.1.2)a ',
- DUMMY_LINE, SEGMENT, STRING132);
- OPTION_KEYWORD := EMPTY_OPTION;
- END
- ELSE IF ERROR_CODE = 1 THEN
- BEGIN
- (* No match found in the table. *)
- DIAG (ERR, 'SCAN_OPTIONS (3.1.2)b ',
- DUMMY_LINE, SEGMENT, STRING132);
- OPTION_KEYWORD := EMPTY_OPTION;
- END (*IF.IF*);
-
- (* Jump to the next OPTION_MARKER in LINE. *)
- WHILE (CH <> RUN_INFO.OPTION_MARKER) AND
- (INDEX<LENGTH_LINE) DO
- BEGIN
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END (*WHILE*);
- END
- ELSE
- OK := TRUE;
- (********************* End of SCAN_OPTIONS (3.1.2) *****************)
-
- IF OK THEN
- BEGIN
- IF OPTION_KEYWORD = OPTION_TABLE[1] THEN
- BEGIN
- SEGMENT_OPTIONS.QUICK := TRUE;
- OPTION_KEYWORD := EMPTY_OPTION;
- END
- ELSE IF OPTION_KEYWORD = OPTION_TABLE[2] THEN
- BEGIN
- SEGMENT_OPTIONS.MULTIPLE := TRUE;
- OPTION_KEYWORD := EMPTY_OPTION;
- END
- ELSE IF OPTION_KEYWORD = OPTION_TABLE[3] THEN
- BEGIN
- SEGMENT_OPTIONS.OPTIONAL := TRUE;
- OPTION_KEYWORD := EMPTY_OPTION;
- END
- ELSE IF OPTION_KEYWORD = OPTION_TABLE[4] THEN
- BEGIN
- (***************** SCAN_OPTIONS (3.1.3) ********************)
- (** Add all characters from INDEX until the next member of **)
- (** OPT_SPACE to the string SEGMENT_OPTIONS.FILE_NAME. **)
- (** Generate a diagnostic message in case of trouble. **)
- WHILE (NOT (CH IN OPT_CHARS)) AND
- (CH <> '"') AND
- (INDEX<LENGTH_LINE) DO
- BEGIN
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END (*WHILE*);
- IF CH = '"' THEN
- BEGIN
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- WHILE (CH <> '"') AND (INDEX < LENGTH_LINE) DO
- BEGIN
- (* SP_ADD_CHAR (UC (CH), SEGMENT_OPTIONS.FILE_NAME); 14/10/93) *)
- SP_ADD_CHAR (CH, SEGMENT_OPTIONS.FILE_NAME);
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END (*WHILE*);
- IF CH = '"' THEN
- BEGIN
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END
- ELSE
- BEGIN
- SP_EXTR_STR (SEGMENT_OPTIONS.FILE_NAME, STRING132);
- DIAG (ERR, 'SCAN_OPTIONS (3.1.3)a ',
- DUMMY_LINE, SEGMENT, STRING132);
- SP_INIT_STR (SEGMENT_OPTIONS.FILE_NAME);
- OPTION_KEYWORD := EMPTY_OPTION;
- END (*IF*);
- END
- ELSE IF (CH IN OPT_CHARS) THEN
- BEGIN
- SP_EXTR_STR (SEGMENT_OPTIONS.FILE_NAME, STRING132);
- DIAG (ERR, 'SCAN_OPTIONS (3.1.3)b ',
- DUMMY_LINE, SEGMENT, STRING132);
- SP_INIT_STR (SEGMENT_OPTIONS.FILE_NAME);
- OPTION_KEYWORD := EMPTY_OPTION;
-
- (* Jump to the next option marker. *)
- WHILE (CH <> RUN_INFO.OPTION_MARKER) AND
- (INDEX<LENGTH_LINE) DO
- BEGIN
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END (*WHILE*);
- END
- ELSE IF INDEX = LENGTH_LINE THEN
- BEGIN
- (* The file specification must be on the next line. *)
- (* Nothing remains to be done here. *)
- END (* IF.IF.IF*);
- (***************** End of SCAN_OPTIONS (3.1.3) *************)
-
- IF NOT SP_IS_EMPTY_STR (SEGMENT_OPTIONS.FILE_NAME) THEN
- OPTION_KEYWORD := EMPTY_OPTION;
- END
- ELSE IF OPTION_KEYWORD = OPTION_TABLE[5] THEN
- BEGIN
- (***************** SCAN_OPTIONS (3.1.4) ********************)
- (** Add all characters from INDEX until the next member of **)
- (** OPT_SPACE to the string SEGMENT_OPTIONS.INDENT. Give an **)
- (** error and initialize SEGMENT_OPTIONS.INDENT and **)
- (** OPTION_KEYWORD and in case of trouble. **)
- WHILE (NOT (CH IN OPT_CHARS)) AND
- (INDEX < LENGTH_LINE) AND
- (CH <> RUN_INFO.OPTION_MARKER) DO
- BEGIN
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END (*WHILE*);
- WHILE (CH IN OPT_CHARS) AND (INDEX < LENGTH_LINE) DO
- BEGIN
- SP_ADD_CHAR (UC (CH), SEGMENT_OPTIONS.INDENT);
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END (*WHILE*);
- IF NOT SP_IS_EMPTY_STR (SEGMENT_OPTIONS.INDENT) THEN
- BEGIN
- SP_EXTR_STR (SEGMENT_OPTIONS.INDENT, STRING132);
- IF ((STRING132.BODY[1] <> 'O') OR
- (STRING132.BODY[2] <> 'N')) AND
- ((STRING132.BODY[1] <> 'O') OR
- (STRING132.BODY[2] <> 'F') OR
- (STRING132.BODY[3] <> 'F')) THEN
- BEGIN
- SP_INIT_STR (SEGMENT_OPTIONS.INDENT);
- OPTION_KEYWORD := EMPTY_OPTION;
- DIAG (ERR, 'SCAN_OPTIONS (3.1.4) ',
- DUMMY_LINE, SEGMENT, STRING132);
- END (*IF*);
- END
- ELSE
- BEGIN
- (* The argument of the INDENT-option must be on the next *)
- (* line. Nothing remains to be done here. *)
- END (*IF*);
- (************* End of SCAN_OPTIONS (3.1.4) *****************)
-
- IF NOT SP_IS_EMPTY_STR (SEGMENT_OPTIONS.INDENT) THEN
- OPTION_KEYWORD := EMPTY_OPTION;
- END
- ELSE IF OPTION_KEYWORD = OPTION_TABLE[6] THEN
- BEGIN
- (***************** SCAN_OPTIONS (3.1.5) ********************)
- (** Add all characters from INDEX until the next member of **)
- (** OPT_SPACE to SEGMENT_OPTIONS.COMMENT. Issue diagnostic **)
- (** and initialize OPTION_KEYWORD and SEGMENT_OPTIONS.- **)
- (** COMMENT in case of trouble. **)
- WHILE (NOT (CH IN OPT_CHARS)) AND
- (INDEX < LENGTH_LINE) AND
- (CH <> RUN_INFO.OPTION_MARKER) DO
- BEGIN
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END (*WHILE*);
- WHILE (CH IN OPT_CHARS) AND (INDEX < LENGTH_LINE) DO
- BEGIN
- SP_ADD_CHAR (UC (CH), SEGMENT_OPTIONS.COMMENT);
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END (*WHILE*);
- IF NOT SP_IS_EMPTY_STR (SEGMENT_OPTIONS.COMMENT) THEN
- BEGIN
- SP_EXTR_STR (SEGMENT_OPTIONS.COMMENT, STRING132);
- IF (STRING132.BODY = PASCAL_STRING) OR
- (STRING132.BODY = FORTRAN_STRING) OR
- (STRING132.BODY = C_STRING) THEN
- BEGIN
- DIAG (WARN, 'SCAN_OPTIONS (3.1.5)a ',
- DUMMY_LINE, SEGMENT, STRING132);
- SP_INIT_STR (SEGMENT_OPTIONS.COMMENT);
- OPTION_KEYWORD := EMPTY_OPTION;
- END
- ELSE IF ((STRING132.BODY[1] <> 'O') OR
- (STRING132.BODY[2] <> 'N')) AND
- ((STRING132.BODY[1] <> 'O') OR
- (STRING132.BODY[2] <> 'F') OR
- (STRING132.BODY[3] <> 'F')) THEN
- BEGIN
- DIAG (ERR, 'SCAN_OPTIONS (3.1.5)b ',
- DUMMY_LINE, SEGMENT, STRING132);
- SP_INIT_STR (SEGMENT_OPTIONS.COMMENT);
- OPTION_KEYWORD := EMPTY_OPTION;
- END (*IF.IF*);
- END
- ELSE
- BEGIN
- (* The argument of the option COMMENT must be on the *)
- (* next line. Nothing remains to be done here *)
- END (*IF*);
- (************* End of SCAN_OPTIONS (3.1.5) *****************)
-
- IF NOT SP_IS_EMPTY_STR (SEGMENT_OPTIONS.COMMENT) THEN
- OPTION_KEYWORD := EMPTY_OPTION;
- END
- ELSE IF OPTION_KEYWORD = OPTION_TABLE[7] THEN
- BEGIN
- SEGMENT_OPTIONS.OVERRULE := TRUE;
- OPTION_KEYWORD := EMPTY_OPTION;
- END
- ELSE IF OPTION_KEYWORD = OPTION_TABLE[8] THEN
- BEGIN
- SEGMENT_OPTIONS.LEADER := TRUE;
- OPTION_KEYWORD := EMPTY_OPTION;
- END
- ELSE IF OPTION_KEYWORD = OPTION_TABLE[9] THEN
- BEGIN
- SEGMENT_OPTIONS.TRAILER := TRUE;
- OPTION_KEYWORD := EMPTY_OPTION;
- END
- ELSE IF OPTION_KEYWORD = OPTION_TABLE[10] THEN
- BEGIN
- SEGMENT_OPTIONS.SEPARATOR := TRUE;
- OPTION_KEYWORD := EMPTY_OPTION;
- END
- ELSE IF OPTION_KEYWORD = OPTION_TABLE[11] THEN
- BEGIN
- SEGMENT_OPTIONS.DEFAULT := TRUE;
- OPTION_KEYWORD := EMPTY_OPTION;
- END
- ELSE IF OPTION_KEYWORD = OPTION_TABLE[12] THEN
- BEGIN
- SEGMENT_OPTIONS.LINENUMBER := TRUE;
- OPTION_KEYWORD := EMPTY_OPTION;
- END (*IF.IF.IF.IF.IF.IF.IF.IF.IF.IF.IF.IF*);
- END (*IF*);
- (***************** End of SCAN_OPTIONS (3.1) ***************)
- END
- ELSE IF CH IN OPT_CHARS THEN
- BEGIN
- (********************* SCAN_OPTIONS (3.2) ******************)
- (** CH is only legal at this point as the first character **)
- (** of the argument of the previous option, i.e. **)
- (** OPTION_KEYWORD must not be empty. Read this argument. **)
- (** When problems arise, jump to next OPTION_MARKER and **)
- (** issue a diagnostic message. **)
- IF OPTION_KEYWORD <> EMPTY_OPTION THEN
- BEGIN
- IF OPTION_KEYWORD = OPTION_TABLE[4] THEN
- BEGIN
- (***************** SCAN_OPTIONS (3.2.1) ********************)
- (** Add characters from INDEX to SEGMENT_OPTIONS.FILE_NAME **)
- (** until the next OPT_SPACE is met. Diagnostic in case of **)
- (** trouble. **)
- WHILE (NOT (CH IN OPT_CHARS)) AND
- (CH <> '"') AND
- (INDEX < LENGTH_LINE) DO
- BEGIN
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END (*WHILE*);
- IF CH = '"' THEN
- BEGIN
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- WHILE (CH <> '"') AND (INDEX <= LENGTH_LINE) DO
- BEGIN
- (* SP_ADD_CHAR (UC (CH), SEGMENT_OPTIONS.FILE_NAME); 14/10/93 *)
- SP_ADD_CHAR (CH, SEGMENT_OPTIONS.FILE_NAME);
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END (*WHILE*);
- IF CH='"' THEN
- BEGIN
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END
- ELSE
- BEGIN
- SP_EXTR_STR (SEGMENT_OPTIONS.FILE_NAME, STRING132);
- DIAG (ERR, 'SCAN_OPTIONS (3.2.1)a ',
- DUMMY_LINE, SEGMENT, STRING132);
- SP_INIT_STR (SEGMENT_OPTIONS.FILE_NAME);
- OPTION_KEYWORD := EMPTY_OPTION;
- END (*IF*);
- END
- ELSE IF (CH IN OPT_CHARS) THEN
- BEGIN
- SP_EXTR_STR (SEGMENT_OPTIONS.FILE_NAME, STRING132);
- DIAG (ERR, 'SCAN_OPTIONS (3.2.1)b ',
- DUMMY_LINE, SEGMENT, STRING132);
- SP_INIT_STR (SEGMENT_OPTIONS.FILE_NAME);
- OPTION_KEYWORD := EMPTY_OPTION;
-
- (* Jump to the next option marker. *)
- WHILE (CH <> RUN_INFO.OPTION_MARKER) AND
- (INDEX<LENGTH_LINE) DO
- BEGIN
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END (*WHILE*);
- END
- ELSE IF INDEX=LENGTH_LINE THEN
- BEGIN
- (* The file specification must be on the next line. *)
- (* Nothing remains to be done here. *)
- END (*IF.IF.IF*);
- (************* End of SCAN_OPTIONS (3.2.1) *****************)
-
- IF NOT SP_IS_EMPTY_STR (SEGMENT_OPTIONS.FILE_NAME) THEN
- OPTION_KEYWORD := EMPTY_OPTION;
- END
- ELSE IF OPTION_KEYWORD=OPTION_TABLE[5] THEN
- BEGIN
- (***************** SCAN_OPTIONS (3.2.2) ********************)
- (** Add characters from INDEX to SEGMENT_OPTIONS.INDENT **)
- (** until the next OPT_SPACE is met. Generate a diagnostic **)
- (** message and reset OPTION_KEYWORD and SEGMENT_OPTIONS.- **)
- (** INDENT in case of trouble. **)
- WHILE (NOT (CH IN OPT_CHARS)) AND
- (INDEX < LENGTH_LINE) DO
- BEGIN
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END (*WHILE*);
- WHILE (CH IN OPT_CHARS) AND
- (INDEX<LENGTH_LINE) DO
- BEGIN
- SP_ADD_CHAR (UC (CH), SEGMENT_OPTIONS.INDENT);
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END (*WHILE*);
- IF NOT SP_IS_EMPTY_STR (SEGMENT_OPTIONS.INDENT) THEN
- BEGIN
- SP_EXTR_STR (SEGMENT_OPTIONS.INDENT, STRING132);
- IF ((STRING132.BODY[1] <> 'O') OR
- (STRING132.BODY[2] <> 'N')) AND
- ((STRING132.BODY[1] <> 'O') OR
- (STRING132.BODY[2] <> 'F') OR
- (STRING132.BODY[3] <> 'F')) THEN
- BEGIN
- SP_INIT_STR (SEGMENT_OPTIONS.INDENT);
- OPTION_KEYWORD := EMPTY_OPTION;
- DIAG (ERR, 'SCAN_OPTIONS (3.2.2) ',
- DUMMY_LINE, SEGMENT, STRING132);
- END (*IF*);
- END
- ELSE
- BEGIN
- (* The argument of the option INDENT must be on the next *)
- (* line. Nothing remains to be done here *)
- END (*IF*);
- (************* End of SCAN_OPTIONS (3.2.2) *****************)
-
- IF NOT SP_IS_EMPTY_STR (SEGMENT_OPTIONS.INDENT) THEN
- OPTION_KEYWORD := EMPTY_OPTION;
- END
- ELSE IF OPTION_KEYWORD=OPTION_TABLE[6] THEN
- BEGIN
- (***************** SCAN_OPTIONS (3.2.3) ********************)
- (** Add characters from INDEX to SEGMENT_OPTIONS.COMMENT **)
- (** until the next OPT_SPACE is met. Generate a diagnostic **)
- (** message and reset OPTION_KEYWORD and SEGMENT_OPTIONS.- **)
- (** COMMENT in case of trouble. **)
- WHILE (NOT (CH IN OPT_CHARS)) AND
- (INDEX<LENGTH_LINE) DO
- BEGIN
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END (*WHILE*);
- WHILE (CH IN OPT_CHARS) AND
- (INDEX<LENGTH_LINE) DO
- BEGIN
- SP_ADD_CHAR (UC (CH), SEGMENT_OPTIONS.COMMENT);
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END (*WHILE*);
- IF NOT SP_IS_EMPTY_STR (SEGMENT_OPTIONS.COMMENT) THEN
- BEGIN
- SP_EXTR_STR (SEGMENT_OPTIONS.COMMENT, STRING132);
- IF (STRING132.BODY = PASCAL_STRING) OR
- (STRING132.BODY = FORTRAN_STRING) OR
- (STRING132.BODY = C_STRING) THEN
- BEGIN
- DIAG (WARN, 'SCAN_OPTIONS (3.2.3)a ',
- DUMMY_LINE, SEGMENT, STRING132);
- SP_INIT_STR (SEGMENT_OPTIONS.COMMENT);
- OPTION_KEYWORD := EMPTY_OPTION;
- END
- ELSE IF ((STRING132.BODY[1] <> 'O') OR
- (STRING132.BODY[2] <> 'N')) AND
- ((STRING132.BODY[1] <> 'O') OR
- (STRING132.BODY[2] <> 'F') OR
- (STRING132.BODY[3] <> 'F')) THEN
- BEGIN
- DIAG (ERR, 'SCAN_OPTIONS (3.2.3)b ',
- DUMMY_LINE, SEGMENT, STRING132);
- SP_INIT_STR (SEGMENT_OPTIONS.COMMENT);
- OPTION_KEYWORD := EMPTY_OPTION;
- END (*IF.IF*);
- END
- ELSE
- BEGIN
- (* The argument of the option COMMENT must be on the *)
- (* next line. Nothing remains to be done here *)
- END (*IF*);
- (************* End of SCAN_OPTIONS (3.2.3) *****************)
- IF NOT SP_IS_EMPTY_STR (SEGMENT_OPTIONS.COMMENT) THEN
- OPTION_KEYWORD := EMPTY_OPTION;
- END (*IF.IF.IF*);
- END
- ELSE
- BEGIN
- (********************* SCAN_OPTIONS (3.2.4) ********************)
- (** Character is illegal at this position. Skip to next **)
- (** OPTION_MARKER or to end of this line. Generate a diagnostic **)
- (** message using SEGMENT and LINE. **)
- STRING132.LENGTH := 1;
- STRING132.BODY[1] := CH;
- DIAG (ERR, 'SCAN_OPTIONS (3.2.4) ', DUMMY_LINE, SEGMENT, STRING132);
- OPTION_KEYWORD := EMPTY_OPTION;
- WHILE (CH <> RUN_INFO.OPTION_MARKER) AND
- (INDEX < LENGTH_LINE) DO
- BEGIN
- INDEX := INDEX + 1;
- CH := FT_GET_CHAR (LINE, INDEX);
- END (*WHILE*);
- (***************** End of SCAN_OPTIONS (3.2.4) *****************)
- END (*IF*);
- (***************** End of SCAN_OPTIONS (3.2) ***************)
- END (*IF*);
- END (*WHILE*);
- (***************** End of SCAN_OPTIONS (3) *************)
-
- (***************** SCAN_OPTIONS (4) ********************)
- (** Retrieve next LINE from SEGMENT. SEGMENT_EXHAUSTED **)
- (** becomes TRUE if the segment is exhausted. **)
- ST_GET_LINE (LINE);
- IF LINE.ID = 0 THEN
- SEGMENT_EXHAUSTED := TRUE;
- (************* End of SCAN_OPTIONS (4) *****************)
- END (*WHILE*);
- IF SEGMENT_EXHAUSTED THEN
- BEGIN
- (***************** SCAN_OPTIONS (5) ********************)
- (** Check SEGMENT_OPTIONS for any errors. and generate **)
- (** diagnostic message using SEGMENT if appropriate. **)
- FT_INIT_LINE (DUMMY_LINE);
-
- (* 1. Check for a missing argument of the last option. *)
- (* This can be detected by a non-empty OPTION_KEYWORD.*)
- IF OPTION_KEYWORD <> EMPTY_OPTION THEN
- BEGIN
- STRING132.LENGTH := 0;
- STRING132.BODY := EMPTY_STRING_FIXED;
- FOR I := 1 TO MAX_OPTION_LENGTH DO
- BEGIN
- IF OPTION_KEYWORD[I] <> ' ' THEN
- BEGIN
- STRING132.BODY[I] := OPTION_KEYWORD[I];
- STRING132.LENGTH := STRING132.LENGTH + 1;
- END (*IF*);
- END (*FOR*);
- DIAG (ERR, 'SCAN_OPTIONS (5a) ', DUMMY_LINE, SEGMENT, STRING132);
- END (*IF*);
-
- (* 2. Check the use of stub options in a slot SEGMENT. *)
- IF (SEGMENT_TYPE = SLOT) OR (SEGMENT_TYPE = CODE) THEN
- BEGIN
- IF SEGMENT_OPTIONS.QUICK THEN
- BEGIN
- SEGMENT_OPTIONS.QUICK := FALSE;
- STRING132.BODY[1] := 'Q';
- STRING132.BODY[2] := 'U';
- STRING132.BODY[3] := 'I';
- STRING132.BODY[4] := 'C';
- STRING132.BODY[5] := 'K';
- STRING132.LENGTH := 5;
- DIAG (ERR, 'SCAN_OPTIONS (5b) ', DUMMY_LINE, SEGMENT,
- STRING132);
- END (*IF*);
- IF NOT (SP_IS_EMPTY_STR (SEGMENT_OPTIONS.FILE_NAME)) THEN
- BEGIN
- SP_INIT_STR (SEGMENT_OPTIONS.FILE_NAME);
- STRING132.BODY[1] := 'F';
- STRING132.BODY[2] := 'I';
- STRING132.BODY[3] := 'L';
- STRING132.BODY[4] := 'E';
- STRING132.LENGTH := 4;
- DIAG (ERR, 'SCAN_OPTIONS (5b) ', DUMMY_LINE, SEGMENT,
- STRING132);
- END (*IF*);
- IF SEGMENT_OPTIONS.OVERRULE THEN
- BEGIN
- SEGMENT_OPTIONS.OVERRULE := FALSE;
- AUX_STRING10 := 'OVERRULE ';
- FOR I:= 1 TO 8 DO
- STRING132.BODY[I] := AUX_STRING10[I];
- STRING132.LENGTH := 8;
- DIAG (ERR, 'SCAN_OPTIONS (5b) ', DUMMY_LINE, SEGMENT,
- STRING132);
- END (*IF*);
- IF SEGMENT_OPTIONS.LEADER THEN
- BEGIN
- SEGMENT_OPTIONS.LEADER := FALSE;
- AUX_STRING10 := 'LEADER ';
- FOR I := 1 TO 6 DO
- STRING132.BODY[I] := AUX_STRING10[I];
- STRING132.LENGTH := 6;
- DIAG (ERR, 'SCAN_OPTIONS (5b) ', DUMMY_LINE, SEGMENT,
- STRING132);
- END (*IF*);
- IF SEGMENT_OPTIONS.TRAILER THEN
- BEGIN
- SEGMENT_OPTIONS.TRAILER := FALSE;
- AUX_STRING10 := 'TRAILER ';
- FOR I:= 1 TO 7 DO
- STRING132.BODY[I] := AUX_STRING10[I];
- STRING132.LENGTH := 7;
- DIAG (ERR, 'SCAN_OPTIONS (5b) ', DUMMY_LINE, SEGMENT,
- STRING132);
- END (*IF*);
- IF SEGMENT_OPTIONS.SEPARATOR THEN
- BEGIN
- SEGMENT_OPTIONS.SEPARATOR := FALSE;
- AUX_STRING10 := 'SEPARATOR ';
- FOR I := 1 TO 9 DO
- STRING132.BODY[I] := AUX_STRING10[I];
- STRING132.LENGTH := 9;
- DIAG (ERR, 'SCAN_OPTIONS (5b) ', DUMMY_LINE, SEGMENT,
- STRING132);
- END (*IF*);
- IF SEGMENT_OPTIONS.DEFAULT THEN
- BEGIN
- SEGMENT_OPTIONS.QUICK := FALSE;
- AUX_STRING10 := 'DEFAULT ';
- FOR I := 1 TO 7 DO
- STRING132.BODY[I] := AUX_STRING10[I];
- STRING132.LENGTH := 7;
- DIAG (ERR, 'SCAN_OPTIONS (5b) ', DUMMY_LINE, SEGMENT,
- STRING132);
- END (*IF*);
- END
-
- (* 3. Check the use of slot options in a stub segment. *)
- ELSE IF SEGMENT_TYPE = STUB THEN
- BEGIN
- IF SEGMENT_OPTIONS.MULTIPLE THEN
- BEGIN
- SEGMENT_OPTIONS.MULTIPLE := FALSE;
- AUX_STRING10 := 'MULTIPLE ';
- FOR I := 1 TO 8 DO
- STRING132.BODY[I] := AUX_STRING10[I];
- STRING132.LENGTH := 8;
- DIAG (ERR, 'SCAN_OPTIONS (5c) ', DUMMY_LINE, SEGMENT,
- STRING132);
- END (*IF*);
- IF SEGMENT_OPTIONS.OPTIONAL THEN
- BEGIN
- SEGMENT_OPTIONS.OPTIONAL := FALSE;
- AUX_STRING10 := 'OPTIONAL ';
- FOR I := 1 TO 8 DO
- STRING132.BODY[I] := AUX_STRING10[I];
- STRING132.LENGTH := 8;
- DIAG (ERR, 'SCAN_OPTIONS (5c) ', DUMMY_LINE, SEGMENT,
- STRING132);
- END (*IF*);
- END (*IF*);
-
- (* 4. Check illegal use of the options FILE, LEADER, *)
- (* TRAILER, SEPARATOR and DEFAULT in the segment. *)
- WITH SEGMENT_OPTIONS DO
- BEGIN
- IF ( (NOT SP_IS_EMPTY_STR (FILE_NAME)) AND
- ( (DEFAULT) OR (SEPARATOR) OR (LEADER) OR (TRAILER))) OR
- ( (DEFAULT) AND ( (SEPARATOR) OR (LEADER) OR (TRAILER))) OR
- ( (LEADER) AND ( (SEPARATOR) OR (TRAILER))) OR
- ( (SEPARATOR) AND (TRAILER)) THEN
- BEGIN
- DEFAULT := FALSE;
- SEPARATOR := FALSE;
- LEADER := FALSE;
- TRAILER := FALSE;
- STRING132.LENGTH := 0;
- STRING132.BODY := EMPTY_STRING_FIXED;
- DIAG (ERR, 'SCAN_OPTIONS (5d) ', DUMMY_LINE, SEGMENT,
- STRING132);
- END (*IF*);
- END (*WITH*);
- (***************** End of SCAN_OPTIONS (5) *************)
- END (*IF*);
- END (*IF*);
- (***************** End of SCAN_OPTIONS (body) ******************)
-
- END (*PROCEDURE SCAN_OPTIONS*);
-
-
- (*********************************************************************)
- (* Routine: BUILD_CODE_STRUCT - BUILD the structure CODE_STRUCT. *)
- (* Purpose: Scan a stub block upon the different sort of *)
- (* segments and build the structure of stubs and slots. *)
- (* Interface: CODE_STRUCT: Anchors the datastructure representing *)
- (* the stubs and slots structure. *)
- (* RUN_INFO: All information concerning this run. *)
- (* FIRST_LINE: The first line of a stub block. *)
- (* LINE_INFO: Scanned information of a line. *)
- (*********************************************************************)
- PROCEDURE BUILD_CODE_STRUCT (VAR CODE_STRUCT: CODE_STRUCT_;
- RUN_INFO: RUN_INFO_;
- FIRST_LINE: LINE_DES_;
- LINE_INFO: LINE_INFO_);
-
- VAR
- SEGMENT_TYPE: SEGMENT_TYPE_;
- END_OF_STUB_BLOCK: BOOLEAN;
- SOURCE_LINE: LINE_DES_;
- LAST_SLOT: SLT_PTR_;
- STRING132: STRING132_;
- SEGMENT: SEGMENT_DES_;
-
- BEGIN
- (******* BUILD_CODE_STRUCT (body) *******)
-
- (********************* BUILD_CODE_STRUCT (1) *******************)
- (** FIRST_LINE marks a new stub segment. Link the stub into its **)
- (** position and let CODE_STRUCT.LAST_STUB refer to it. Set **)
- (** LAST_SLOT to NIL. Initialize LAST_STUB. Add FIRST_LINE to **)
- (** the segment LAST_STUB^.SRC_IMG. Use LINE_INFO to update **)
- (** LAST_STUB^.NAME. **)
- WITH CODE_STRUCT DO
- BEGIN
- LAST_SLOT := NIL;
- IF FIRST_STUB = NIL THEN
- BEGIN
- NEW (FIRST_STUB);
- LAST_STUB := FIRST_STUB;
- END
- ELSE
- BEGIN
- NEW (LAST_STUB^.NEXT_STUB);
- LAST_STUB := LAST_STUB^.NEXT_STUB;
- END (*IF*);
- WITH LAST_STUB^ DO
- BEGIN
- SLOTS := NIL;
- NEXT_STUB := NIL;
- NEXT_TWIN := NIL;
- ST_INIT_SEG (SRC_IMG);
- SP_INIT_STR (NAME);
- ST_PUT_SEG (FIRST_LINE, SRC_IMG);
- SP_ADD_BUFFER (LINE_INFO.LINE_ID);
- SP_CONC_STR (NAME, LINE_INFO.LINE_ID);
- END (*WITH*);
- END (*WITH*);
- (***************** End of BUILD_CODE_STRUCT (1) ****************)
-
- (* Set SEGMENT_TYPE to STUB since the first segment of a stub *)
- (* block must be a stub segment. Initialize END_OF_STUB_BLOCK. *)
- SEGMENT_TYPE := STUB;
- END_OF_STUB_BLOCK := FALSE;
-
- WHILE (NOT END_OF_STUB_BLOCK) AND (NOT FT_EOF) DO
- BEGIN
- FT_RDLN (SOURCE_LINE);
-
- (* Check wether or not we need to scan this line. *)
- WITH RUN_INFO DO
- BEGIN
- IF FT_GET_LINE_LENGTH (SOURCE_LINE) >
- CLIP_LPAR.LENGTH+CLIP_RPAR.LENGTH THEN
- SCAN_LINE (LINE_INFO, SOURCE_LINE, RUN_INFO)
- ELSE
- LINE_INFO.CATEGORY := L5;
- END (*WITH*);
-
- WITH CODE_STRUCT DO
- CASE LINE_INFO.CATEGORY OF
- L1:
- BEGIN
- IF LAST_SLOT = NIL THEN
- BEGIN
- (************* BUILD_CODE_STRUCT (2) ***************)
- (** The end of the previous stub segment. Scan the **)
- (** options of LAST_STUB^.SRC_IMG and store the **)
- (** found options in LAST_STUB^.OPTIONS. Add the **)
- (** buffer to LINE_INFO.LINE_ID. **)
- WITH LAST_STUB^ DO
- SCAN_OPTIONS (OPTIONS, SRC_IMG, RUN_INFO, SEGMENT_TYPE);
- LINE_INFO.OPTIONS := FALSE;
- SP_ADD_BUFFER (LINE_INFO.LINE_ID);
- (********* End of BUILD_CODE_STRUCT (2) ************)
-
- IF LAST_STUB^.OPTIONS.QUICK THEN
- BEGIN
- SEGMENT_TYPE := STUB;
- (************* BUILD_CODE_STRUCT (3) ***********)
- (** The end of the current stub block and the **)
- (** start a new one. Make an entry for this new **)
- (** stub, let LAST_STUB point to it and initia- **)
- (** lize its fields. Set LAST_SLOT to NIL. Add **)
- (** SOURCE_LINE to LAST_STUB^.SRC_IMG. Update **)
- (** LAST_STUB^.NAME with information from **)
- (** LINE_INFO. **)
- NEW (LAST_STUB^.NEXT_STUB);
- LAST_STUB := LAST_STUB^.NEXT_STUB;
- LAST_SLOT := NIL;
- WITH LAST_STUB^ DO
- BEGIN
- SLOTS := NIL;
- NEXT_STUB := NIL;
- NEXT_TWIN := NIL;
- ST_INIT_SEG (SRC_IMG);
- SP_INIT_STR (NAME);
- ST_PUT_SEG (SOURCE_LINE, SRC_IMG);
- SP_CONC_STR (NAME, LINE_INFO.LINE_ID);
- END (*WITH*);
- (********* End of BUILD_CODE_STRUCT (3) ********)
- END
- ELSE
- BEGIN
- SEGMENT_TYPE := SLOT;
- (************* BUILD_CODE_STRUCT (4) ***********)
- (** First slot segment of this stub block. Make **)
- (** entry for this new slot, let LAST_SLOT **)
- (** point to it and initialize its fields. Add **)
- (** SOURCE_LINE to segment LAST_SLOT^.SRC_IMG. **)
- (** Update LAST_SLOT with the information hold **)
- (** by LINE_INFO. **)
- NEW (LAST_STUB^.SLOTS);
- LAST_SLOT := LAST_STUB^.SLOTS;
- WITH LAST_SLOT^ DO
- BEGIN
- SP_INIT_STR (NAME);
- ST_INIT_SEG (SRC_IMG);
- STUB_REF := NIL;
- ST_INIT_SEG (CODE);
- NEXT_SLOT := NIL;
- ST_PUT_SEG (SOURCE_LINE, SRC_IMG);
- SP_CONC_STR (NAME, LINE_INFO.LINE_ID);
- END (*WITH*);
- (********* End of BUILD_CODE_STRUCT (4) ********)
- END (*IF*);
- END
- ELSE
- BEGIN
- (************* BUILD_CODE_STRUCT (5) ***************)
- (** End of the previous segment LAST_SLOT^.SRC_IMG. **)
- (** Finish the segment by scanning its options **)
- (** using RUN_INFO. Store found options in **)
- (** LAST_SLOT^.OPTIONS. Add the buffer to LINE_- **)
- (** INFO.LINE_ID. **)
- WITH LAST_SLOT^ DO
- SCAN_OPTIONS (OPTIONS, SRC_IMG, RUN_INFO, SEGMENT_TYPE);
- LINE_INFO.OPTIONS := FALSE;
- SP_ADD_BUFFER (LINE_INFO.LINE_ID);
- (********* End of BUILD_CODE_STRUCT (5) ************)
- IF LAST_STUB^.OPTIONS.QUICK THEN
- BEGIN
- SEGMENT_TYPE := STUB;
- (************* BUILD_CODE_STRUCT (6) ***********)
- (** End of current stub block and the start of **)
- (** a new one. Link this new stub into its po- **)
- (** sition, let LAST_STUB point to it and ini- **)
- (** tialize its fields. Add SOURCE_LINE to **)
- (** segment LAST_STUB^.SRC_IMG and update **)
- (** LAST_STUB^.NAME with the help of LINE_INFO. **)
- NEW (LAST_STUB^.NEXT_STUB);
- LAST_STUB := LAST_STUB^.NEXT_STUB;
- LAST_SLOT := NIL;
- WITH LAST_STUB^ DO
- BEGIN
- SLOTS := NIL;
- NEXT_STUB := NIL;
- NEXT_TWIN := NIL;
- ST_INIT_SEG (SRC_IMG);
- SP_INIT_STR (NAME);
- ST_PUT_SEG (SOURCE_LINE, SRC_IMG);
- SP_CONC_STR (NAME, LINE_INFO.LINE_ID);
- END (*WITH*);
- (********* End of BUILD_CODE_STRUCT (6) ********)
- END
- ELSE
- BEGIN
- SEGMENT_TYPE := SLOT;
- (************* BUILD_CODE_STRUCT (7) ***********)
- (** Start of a new slot segment. Link slot into **)
- (** its position, let LAST_SLOT point to it and **)
- (** initialize its fields. Add SOURCE_LINE to **)
- (** LAST_SLOT^.SRC_IMG and update LAST_SLOT^.- **)
- (** NAME with the help of LINE_INFO. **)
- NEW (LAST_SLOT^.NEXT_SLOT);
- LAST_SLOT := LAST_SLOT^.NEXT_SLOT;
- WITH LAST_SLOT^ DO
- BEGIN
- SP_INIT_STR (NAME);
- ST_INIT_SEG (SRC_IMG);
- STUB_REF := NIL;
- ST_INIT_SEG (CODE);
- NEXT_SLOT := NIL;
- ST_PUT_SEG (SOURCE_LINE, SRC_IMG);
- SP_CONC_STR (NAME, LINE_INFO.LINE_ID);
- END (*WITH*);
- (********* End of BUILD_CODE_STRUCT (7) ********)
- END (*IF*);
- END(*IF*);
- END;
- L2:
- BEGIN
- (***************** BUILD_CODE_STRUCT (8) ***************)
- (** End of the previous slot or stub segment. Scan **)
- (** LAST_<x>^.SRC_IMG for options and store them in **)
- (** LAST_<x>^.OPTIONS. Add the buffer to LINE_INFO.- **)
- (** LINE_ID after that. <x> reads "STUB" for a stub **)
- (** and "SLOT" for a slot- or code-segment. **)
- IF (SEGMENT_TYPE = STUB) THEN
- BEGIN
- WITH LAST_STUB^ DO
- SCAN_OPTIONS (OPTIONS, SRC_IMG, RUN_INFO, SEGMENT_TYPE)
- END
- ELSE
- BEGIN
- WITH LAST_SLOT^ DO
- SCAN_OPTIONS (OPTIONS, SRC_IMG, RUN_INFO, SEGMENT_TYPE);
- END (*IF*);
- LINE_INFO.OPTIONS := FALSE;
- SP_ADD_BUFFER (LINE_INFO.LINE_ID);
- (************* End of BUILD_CODE_STRUCT (8) ************)
-
- END_OF_STUB_BLOCK := TRUE;
- SEGMENT_TYPE := END_STUB;
-
- (***************** BUILD_CODE_STRUCT (9) ***************)
- (** Start of the end segment. Link slot into its posi- **)
- (** tion, let LAST_SLOT point to it and initialize its **)
- (** fields. Add SOURCE_LINE to the segment LAST_SLOT^.- **)
- (** SRC_IMG and update LAST_SLOT^.NAME using the infor- **)
- (** mation of LINE_INFO. **)
- IF LAST_SLOT<>NIL THEN
- BEGIN
- NEW (LAST_SLOT^.NEXT_SLOT);
- LAST_SLOT := LAST_SLOT^.NEXT_SLOT;
- END
- ELSE
- BEGIN
- NEW (LAST_STUB^.SLOTS);
- LAST_SLOT := LAST_STUB^.SLOTS;
- END (*IF*);
- WITH LAST_SLOT^ DO
- BEGIN
- SP_INIT_STR (NAME);
- ST_INIT_SEG (SRC_IMG);
- STUB_REF := NIL;
- ST_INIT_SEG (CODE);
- NEXT_SLOT := NIL;
- SCAN_OPTIONS (OPTIONS, SRC_IMG, RUN_INFO, SEGMENT_TYPE);
- LINE_INFO.OPTIONS := FALSE;
- ST_PUT_SEG (SOURCE_LINE, SRC_IMG);
- SP_CONC_STR (NAME, LINE_INFO.LINE_ID);
- END; (*WITH*)
- (************* End of BUILD_CODE_STRUCT (9) ************)
- END;
- L3:
- BEGIN
- IF SEGMENT_TYPE = STUB THEN
- BEGIN
- (************* BUILD_CODE_STRUCT (10) **************)
- (** Continuation line of the stub segment. Add **)
- (** SOURCE_LINE to LAST_STUB^.SRC_IMG. Add buffer **)
- (** to LINE_INFO.LINE_ID and update LAST_STUB^.NAME **)
- (** using LINE_INFO. **)
- WITH LAST_STUB^ DO
- BEGIN
- ST_PUT_LINE (SOURCE_LINE, SRC_IMG);
- SP_ADD_BUFFER (LINE_INFO.LINE_ID);
- SP_CONC_STR (NAME, LINE_INFO.LINE_ID);
- END (*WITH*);
- (********* End of BUILD_CODE_STRUCT (10) ***********)
- END
- ELSE IF SEGMENT_TYPE = SLOT THEN
- BEGIN
- (************* BUILD_CODE_STRUCT (11) **************)
- (** Continuation of the current slot segment. **)
- (** Add SOURCE_LINE to LAST_SLOT^.SRC_IMG, add the **)
- (** buffer to LINE_INFO.LINE_ID and update LAST_- **)
- (** SLOT^.NAME using LINE_INFO. **)
- WITH LAST_SLOT^ DO
- BEGIN
- ST_PUT_LINE (SOURCE_LINE, SRC_IMG);
- SP_ADD_BUFFER (LINE_INFO.LINE_ID);
- SP_CONC_STR (NAME, LINE_INFO.LINE_ID);
- END (*WITH*);
- (********* End of BUILD_CODE_STRUCT (11) ***********)
- END
- ELSE
- BEGIN
- (************* BUILD_CODE_STRUCT (12) **************)
- (** This orphan line cannot be paste to a stub- or **)
- (** slot-segment. Generate an error message using **)
- (** the information hold by SOURCE_LINE. **)
- ST_INIT_SEG (SEGMENT);
- STRING132.LENGTH := 0;
- STRING132.BODY := EMPTY_STRING_FIXED;
- DIAG (WARN, 'BUILD_C_S (12) ', SOURCE_LINE, SEGMENT, STRING132);
- (********* End of BUILD_CODE_STRUCT (12) ***********)
- END (*IF.IF*);
- END;
- L4:
- BEGIN
- IF SEGMENT_TYPE = STUB THEN
- BEGIN
- (************* BUILD_CODE_STRUCT (13) **************)
- (** Continuation ofcurrent stub segment. Add **)
- (** SOURCE_LINE to segment LAST_STUB^.SRC_IMG. **)
- WITH LAST_STUB^ DO
- ST_PUT_LINE (SOURCE_LINE, SRC_IMG);
- (********* End of BUILD_CODE_STRUCT (13) ***********)
- END
- ELSE IF SEGMENT_TYPE = SLOT THEN
- BEGIN
- (************* BUILD_CODE_STRUCT (14) **************)
- (** Continuation of current slot segment. Add **)
- (** SOURCE_LINE to segment LAST_SLOT^.SRC_IMG. **)
- WITH LAST_SLOT^ DO
- ST_PUT_LINE (SOURCE_LINE, SRC_IMG);
- (********* End of BUILD_CODE_STRUCT (14) ***********)
- END
- ELSE IF SEGMENT_TYPE = CODE THEN
- BEGIN
- (************* BUILD_CODE_STRUCT (15) **************)
- (** Continuation of current code segment. Add **)
- (** SOURCE_LINE to segment LAST_SLOT^.CODE. **)
- WITH LAST_SLOT^ DO
- ST_PUT_LINE (SOURCE_LINE, CODE);
- (********* End of BUILD_CODE_STRUCT (15) ***********)
- END (*IF.IF.IF*);
- END;
- L5:
- BEGIN
- IF SEGMENT_TYPE = STUB THEN
- BEGIN
- (************* BUILD_CODE_STRUCT (16) **************)
- (** End of previous stub segment LAST_STUB^.- **)
- (** SRC_IMG. Complete that segment by scanning **)
- (** which are stored to LAST_STUB^.OPTIONS. **)
- WITH LAST_STUB^ DO
- SCAN_OPTIONS (OPTIONS, SRC_IMG, RUN_INFO, SEGMENT_TYPE);
- LINE_INFO.OPTIONS := FALSE;
- (********* End of BUILD_CODE_STRUCT (16) ***********)
-
- IF (LAST_STUB^.OPTIONS.QUICK) AND
- (FT_GET_LINE_LENGTH (SOURCE_LINE) = 0) THEN
- BEGIN
- (************* BUILD_CODE_STRUCT (17) **********)
- (** End of current stub block. Set Boolean **)
- (** END_OF_STUB_BLOCK to TRUE. **)
- END_OF_STUB_BLOCK := TRUE;
- (********* End of BUILD_CODE_STRUCT (17) *******)
- END
- ELSE
- BEGIN
- SEGMENT_TYPE := CODE;
- (************* BUILD_CODE_STRUCT (18) **********)
- (** Start of a new code-segment. Link a new **)
- (** entry for this slot into its position. Let **)
- (** LAST_SLOT refer to this slot and initialize **)
- (** its fields. Add SOURCE_LINE to the new code **)
- (** segment LAST_SLOT^.CODE. **)
- NEW (LAST_STUB^.SLOTS);
- LAST_SLOT := LAST_STUB^.SLOTS;
- WITH LAST_SLOT^ DO
- BEGIN
- SP_INIT_STR (NAME);
- ST_INIT_SEG (SRC_IMG);
- STUB_REF := NIL;
- ST_INIT_SEG (CODE);
- NEXT_SLOT := NIL;
- ST_PUT_SEG (SOURCE_LINE, CODE);
- END (*WITH*);
- (********* END OF BUILD_CODE-STRUCT (18) *******)
- END (*IF.IF*);
- END
- ELSE IF SEGMENT_TYPE = SLOT THEN
- BEGIN
- SEGMENT_TYPE := CODE;
- (************* BUILD_CODE_STRUCT (19) **************)
- (** Start of a new code segment immediately follo- **)
- (** wing a slot segment. Add SOURCE_LINE to the **)
- (** to the code segment LAST_SLOT^.CODE. **)
- WITH LAST_SLOT^ DO
- ST_PUT_SEG (SOURCE_LINE, CODE);
- (********* End of BUILD_CODE_STRUCT (19) ***********)
- END
- ELSE IF SEGMENT_TYPE = CODE THEN
- BEGIN
- IF (CODE_STRUCT.LAST_STUB^.OPTIONS.QUICK) AND
- (FT_GET_LINE_LENGTH (SOURCE_LINE)=0) THEN
- BEGIN
- (************* BUILD_CODE_STRUCT (20) **********)
- (** End of current stub block. Scan options **)
- (** from LAST_SLOT^.SRC_IMG and store them in **)
- (** LAST_SLOT^.OPTIONS. **)
- SCAN_OPTIONS (LAST_SLOT^.OPTIONS, LAST_SLOT^.SRC_IMG,
- RUN_INFO, SEGMENT_TYPE);
- LINE_INFO.OPTIONS := FALSE;
- (********* End of BUILD_CODE_STRUCT (20) *******)
-
- END_OF_STUB_BLOCK := TRUE;
- END
- ELSE
- BEGIN
- (************* BUILD_CODE_STRUCT (21) **********)
- (** Continuation of the code segment. Add **)
- (** SOURCE_LINE to segment LAST_SLOT^.CODE. **)
- WITH LAST_SLOT^ DO
- ST_PUT_LINE (SOURCE_LINE, CODE);
- (********* End of BUILD_CODE_STRUCT (21) *******)
- END (*IF*);
- END (*IF.IF.IF*);
- END;
- END (*CASE.WITH*);
- END (*WHILE*);
-
- IF (NOT END_OF_STUB_BLOCK) THEN
- BEGIN
- IF (NOT CODE_STRUCT.LAST_STUB^.OPTIONS.QUICK) THEN
- BEGIN
- (************* BUILD_CODE_STRUCT (22) ******************)
- (** File exhausted but current stub block not closed by **)
- (** a line of category L2. Issue an error using **)
- (** FILE_SPEC. **)
- STRING132.LENGTH := 0;
- STRING132.BODY := EMPTY_STRING_FIXED;
- FT_INIT_LINE (SOURCE_LINE);
- DIAG (WARN, 'BUILD_C_S (22) ', SOURCE_LINE,
- CODE_STRUCT.LAST_STUB^.SRC_IMG, STRING132);
- (************* End of BUILD_CODE_STRUCT (22) ***********)
- END
- ELSE IF SEGMENT_TYPE = CODE THEN
- BEGIN
- (************* BUILD_CODE_STRUCT (23) ******************)
- (** The last quick stub in the file didn't end with an **)
- (** L5-line, but with EOF. So the options from LAST_- **)
- (** SLOT.SRC_IMG must be scanned and stored in LAST_- **)
- (** SLOT.OPTIONS here. **)
- SCAN_OPTIONS (LAST_SLOT^.OPTIONS, LAST_SLOT^.SRC_IMG,
- RUN_INFO, SEGMENT_TYPE);
- LINE_INFO.OPTIONS := FALSE;
- (************* End of BUILD_CODE_STRUCT (23) ***********)
- END (*IF*);
- END (*IF*);
- (************* End of BUILD_CODE_STRUCT (body) *****************)
-
- END (*PROCEDURE BUILD_CODE_STRUCT*);
-
-
- (*********************************************************************)
- (* Routine: SCAN_FILES - SCAN all source FILES. *)
- (* Purpose: To coordinate the scanning of all the sourcefiles on *)
- (* file level. More detailed activities are delegated. *)
- (* Interface: RUN_INFO: Structure containing all needed info *)
- (* for this CLIP run. *)
- (* CODE_STRUCT: Internal representation of stub-, *)
- (* slot- and code-segments. *)
- (*********************************************************************)
- PROCEDURE SCAN_FILES (VAR CODE_STRUCT: CODE_STRUCT_;
- RUN_INFO: RUN_INFO_);
-
- VAR
- SCAN_FILE_STOP: BOOLEAN;
- FILE_CNT: INTEGER;
- I: INTEGER;
- LINE_INFO: LINE_INFO_ ;
- SOURCE_LINE: LINE_DES_ ;
- DUMMY: ERROR_CODE_;
- STRING132: STRING132_;
- SEGMENT: SEGMENT_DES_;
-
- BEGIN
- (******* SCAN_FILES (body) *******)
- SCAN_FILE_STOP := FALSE;
-
- (********************* SCAN_FILES (1) **************************)
- (** Try to open all source files of which the names are kept by **)
- (** RUN_INFO. List inaccessible files. Set SCAN_FILE_STOP to **)
- (** TRUE when at least one file gives a problem. **)
- WITH RUN_INFO DO
- FOR FILE_CNT := 1 TO NR_SRC_FILES DO
- BEGIN
- IF FT_CHECK_FILE (SOURCE_FILES [FILE_CNT]) <> 0 THEN
- BEGIN
- WRITE ('ERROR checking source file: ');
- FOR I := 1 TO SOURCE_FILES [FILE_CNT].LENGTH DO
- WRITE (SOURCE_FILES [FILE_CNT].BODY [I]);
- WRITELN;
-
- IF REPORT_OK THEN
- BEGIN
- WRITE (REPORT_FILE, 'ERROR checking source file: ');
- FOR I := 1 TO SOURCE_FILES [FILE_CNT].LENGTH DO
- WRITE (REPORT_FILE, SOURCE_FILES [FILE_CNT].BODY [I]);
- WRITELN (REPORT_FILE);
- END (*IF*);
-
- SCAN_FILE_STOP := TRUE;
- END (*IF*);
- END (*FOR.WITH*);
- (***************** End of SCAN_FILES (1) ***********************)
-
- IF NOT SCAN_FILE_STOP THEN
- BEGIN
- (********************* SCAN_FILES (2) **********************)
- (** Build CODE_STRUCT from the source files specified by **)
- (** RUN_INFO. **)
- FOR FILE_CNT := 1 TO RUN_INFO.NR_SRC_FILES DO
- BEGIN
- (* Open and reset file with given specification using *)
- (* the function FT_INOPEN from the module FT. *)
- IF FT_INOPEN (RUN_INFO.SOURCE_FILES [FILE_CNT]) <= 0 THEN
- BEGIN
- WRITE ('Scanning file: ');
- FOR I := 1 TO RUN_INFO.SOURCE_FILES [FILE_CNT].LENGTH DO
- WRITE (RUN_INFO.SOURCE_FILES [FILE_CNT].BODY[I]);
- WRITELN;
-
- IF REPORT_OK THEN
- BEGIN
- WRITE (REPORT_FILE, 'Scanning file: ');
- FOR I := 1 TO RUN_INFO.SOURCE_FILES [FILE_CNT].LENGTH DO
- WRITE (REPORT_FILE,
- RUN_INFO.SOURCE_FILES [FILE_CNT].BODY[I]);
- WRITELN (REPORT_FILE);
- END (*IF*);
-
- WHILE NOT FT_EOF DO
- BEGIN
- (* Read the next line from the source file and *)
- (* initialize LINE_INFO and the Buffer. *)
- FT_RDLN (SOURCE_LINE);
- WITH LINE_INFO DO
- OPTIONS := FALSE;
- SP_INIT_BUFFER;
-
- (* Determine the category this line belongs to. *)
- WITH RUN_INFO DO
- BEGIN
- IF SOURCE_LINE.USED >
- CLIP_LPAR.LENGTH + CLIP_RPAR.LENGTH THEN
- SCAN_LINE (LINE_INFO, SOURCE_LINE, RUN_INFO)
- ELSE
- LINE_INFO.CATEGORY := L5;
- END (*WITH*);
-
- (* Proces this line according to its catagory. *)
- CASE LINE_INFO.CATEGORY OF
- L1:
- BEGIN
- (************* SCAN_FILES (2.1) ********************)
- (** Start of a new stub. Switch to active mode and **)
- (** build CODE_STRUCT from successive lines using **)
- (** RUN_INFO, SOURCE_LINE and LINE_INFO. **)
-
- BUILD_CODE_STRUCT (CODE_STRUCT, RUN_INFO, SOURCE_LINE, LINE_INFO);
-
- (************* End of SCAN_FILES (2.1) *************)
- END;
- L2:
- BEGIN
- (************* SCAN_FILES (2.2) ********************)
- (** Illegal in passive mode. Generate an error from **)
- (** the information in SOURCE_LINE. **)
- ST_INIT_SEG (SEGMENT);
- STRING132.BODY := EMPTY_STRING_FIXED;
- STRING132.LENGTH := 0;
- DIAG (WARN, 'SCAN_FILES (2.2) ', SOURCE_LINE, SEGMENT, STRING132);
- (************* End of SCAN_FILES (2.2) *************)
- END;
- L3:
- BEGIN
- (************* SCAN_FILES (2.3) ********************)
- (** Illegal in passive mode. Generate an error from **)
- (** the information in SOURCE_LINE. **)
- ST_INIT_SEG (SEGMENT);
- STRING132.LENGTH := 0;
- STRING132.BODY := EMPTY_STRING_FIXED;
- DIAG (ERR, 'SCAN_FILES (2.3) ', SOURCE_LINE, SEGMENT, STRING132);
- (************* End of SCAN_FILES (2.3) *************)
- END;
- L4,
- L5:
- BEGIN
- (* Nothing to be done. Flush this line. *)
- END;
- END (*CASE*);
- END (*WHILE*);
- DUMMY := FT_INCLOSE;
- END
- ELSE
- BEGIN
- (********************* SCAN_FILES (2.4) ********************)
- (** Access problem with this source file. Issue error using **)
- (** its specification in RUN_INFO. **)
- WITH RUN_INFO DO
- BEGIN
- WRITE ('ERROR opening source file: ');
- FOR I := 1 TO SOURCE_FILES [FILE_CNT].LENGTH DO
- WRITE (SOURCE_FILES [FILE_CNT].BODY [I]);
- WRITELN;
-
- IF REPORT_OK THEN
- BEGIN
- WRITE (REPORT_FILE, 'ERROR opening source file: ');
- FOR I := 1 TO SOURCE_FILES [FILE_CNT].LENGTH DO
- WRITE (REPORT_FILE, SOURCE_FILES [FILE_CNT].BODY [I]);
- WRITELN (REPORT_FILE);
- END (*IF*);
- END (*WITH*);
- (***************** End of SCAN_FILES (2.4) *****************)
- END (*IF*);
- END (*FOR*);
- (***************** End of SCAN_FILES (2) *******************)
- END (*IF*);
- (***************** End of SCAN_FILES (body) ********************)
- END (*PROCEDURE SCAN_FILES*);
-
-
- (*********************************************************************)
- (* Routine: CHECK_CIRC - CHECK FOR CIRCularity. *)
- (* Purpose: To check possible circularity of CODE_STRUCT. *)
- (* Interface: CODE_STRUCT - Structure to be examined. *)
- (* LIST_HEAD - First element of shadow list. *)
- (*********************************************************************)
- PROCEDURE CHECK_CIRC (VAR CODE_STRUCT: CODE_STRUCT_;
- LIST_HEAD: SHADOW_PTR_);
-
- VAR
- MAIN_STUB: STB_PTR_;
- SHADOW_STUB: SHADOW_PTR_;
- STUB: STB_PTR_;
- CIRCULARITY,
- REMOVED: BOOLEAN;
-
- (******* CHECK_CIRC routines *******)
-
- (*********************************************************************)
- (* Routine: LOCATE_CIRC - LOCATE CIRCularity. *)
- (* Purpose: Locate and remove circularity in CODE_STRUCT. *)
- (* Interface: CODE_STRUCT - The structure to be checked. *)
- (* STUB - The stub currently checked. *)
- (* CIRCULARITY - Flags if circularity is detected. *)
- (* REMOVED - Flags if circularity is removed. *)
- (*********************************************************************)
- PROCEDURE LOCATE_CIRC (VAR CODE_STRUCT: CODE_STRUCT_;
- VAR STUB: STB_PTR_;
- VAR CIRCULARITY: BOOLEAN;
- VAR REMOVED: BOOLEAN);
-
- (******* LOCATE_CIRC labels (#Quick) *******)
- LABEL
- MYEXIT;
-
- VAR
- SLOT: SLT_PTR_;
- HELP_STUB: STB_PTR_;
- TWIN_STUB: STB_PTR_;
-
- (******* LOCATE_CIRC routines *******)
-
- (*********************************************************************)
- (* Routine: TRACEBACK *)
- (* Purpose: -In case of an unremoved circularity: Remove circu- *)
- (* larity and show the responsible slot. *)
- (* -Show a stub of the circularity-chain. *)
- (* Interface: STUB - The stub, which was being checked. *)
- (* SLOT - The slot, at which STUB is pointing. *)
- (* REMOVED - Flags if the circularity is removed. *)
- (*********************************************************************)
- PROCEDURE TRACEBACK ( STUB: STB_PTR_;
- SLOT: SLT_PTR_;
- VAR REMOVED: BOOLEAN);
- BEGIN
- IF NOT REMOVED THEN
- BEGIN
- SLOT^.STUB_REF := NIL;
- REMOVED := TRUE;
- WRITELN('Circularity detected !!! TRACE BACK:');
- WRITELN ('slot:');
- ST_WRITE_SEG (SLOT^.SRC_IMG, 0, 0);
- WRITELN;
-
- IF REPORT_OK THEN
- BEGIN
- WRITELN (REPORT_FILE,
- 'Circularity detected !!! TRACE BACK:');
- WRITELN (REPORT_FILE, 'slot:');
- ST_WRITE_SEG (SLOT^.SRC_IMG, 0, 3);
- WRITELN (REPORT_FILE);
- END (*IF*);
-
- END(*IF*);
- IF NOT SP_IS_EMPTY_STR (STUB^.OPTIONS.FILE_NAME) THEN
- BEGIN
- WRITELN ('Main stub:');
- ST_WRITE_SEG (STUB^.SRC_IMG, 0, 0);
- WRITELN ('------------------------------------',
- '------------------------------------');
-
- IF REPORT_OK THEN
- BEGIN
- WRITELN (REPORT_FILE, 'Main stub:');
- ST_WRITE_SEG (STUB^.SRC_IMG, 0, 3);
- WRITELN (REPORT_FILE,
- '------------------------------------',
- '------------------------------------');
- END (*IF*);
- END
- ELSE
- BEGIN
- WRITELN ('Stub:');
- ST_WRITE_SEG (STUB^.SRC_IMG, 0, 0);
-
- IF REPORT_OK THEN
- BEGIN
- WRITELN (REPORT_FILE, 'Stub:');
- ST_WRITE_SEG (STUB^.SRC_IMG, 0, 3);
- END (*IF*);
- END (*IF*);
- WRITELN;
- END (*TRACEBACK*);
- (********************* End of LOCATE_CIRC routines *****************)
-
- BEGIN
- (******* LOCATE_CIRC (body) *******)
- WITH STUB^ DO
- BEGIN
- CIRCULARITY := STUB^.VISITED;
- IF NOT CIRCULARITY THEN
- BEGIN
- STUB^.VISITED := TRUE;
- SLOT := STUB^.SLOTS;
-
- (********************* LOCATE_CIRC (1) *********************)
- (** Check if the SLOTs of STUB are pointing at any stubs. **)
- (** If so, locate circularities in these stubs and their **)
- (** structure behind. Leave this level of the procedure **)
- (** through MYEXIT in case of circularity. **)
- WHILE SLOT <> NIL DO
- BEGIN
- IF SLOT^.STUB_REF <> NIL THEN
- BEGIN
- LOCATE_CIRC(CODE_STRUCT,SLOT^.STUB_REF,
- CIRCULARITY,REMOVED);
- IF CIRCULARITY THEN
- BEGIN
- (***************** LOCATE_CIRC (1.1) *******************)
- (** Remove the link causing the circularity in CODE_- **)
- (** STRUCT, if not removed already. Mention STUB in the **)
- (** traceback. If this STUB is a main stub, set CIRCU- **)
- (** RITY, REMOVED and VISITED of all next stubs back to **)
- (** FALSE and locate circularities in this new CODE_- **)
- (** STRUCT. Leave this level of the procedure through **)
- (** MYEXIT. **)
- TRACEBACK (STUB, SLOT, REMOVED);
- IF NOT SP_IS_EMPTY_STR (STUB^.OPTIONS.FILE_NAME) THEN
- BEGIN
- CIRCULARITY := FALSE;
- REMOVED := FALSE;
- HELP_STUB := STUB;
- WHILE HELP_STUB <> NIL DO
- BEGIN
- HELP_STUB^.VISITED := FALSE;
- HELP_STUB := HELP_STUB^.NEXT_STUB;
- END (*WHILE*);
- LOCATE_CIRC (CODE_STRUCT, STUB, CIRCULARITY, REMOVED);
- END(*IF*);
- GOTO MYEXIT;
- (************* End of LOCATE_CIRC (1.1) ****************)
- END (*IF*);
-
- (***************** LOCATE_CIRC (1.2) ***********************)
- (** Check if SLOT^.STUB_REF is pointing at any twin stubs. **)
- (** If so, locate circularities in these stubs. In case of **)
- (** circularity, remove the responsible link, if not **)
- (** removed already, mention STUB in the traceback and **)
- (** leave this level of the procedure through MYEXIT. **)
- TWIN_STUB := SLOT^.STUB_REF^.NEXT_TWIN;
- WHILE TWIN_STUB <> NIL DO
- BEGIN
- LOCATE_CIRC (CODE_STRUCT, TWIN_STUB, CIRCULARITY, REMOVED);
- IF CIRCULARITY THEN
- BEGIN
- TRACEBACK (STUB, SLOT, REMOVED);
- GOTO MYEXIT;
- END (*IF*);
- TWIN_STUB := TWIN_STUB^.NEXT_TWIN;
- END (*WHILE*);
- (************* End of LOCATE_CIRC (1.2) ********************)
-
- SLOT^.STUB_REF^.VISITED := FALSE;
- END (*IF*);
- SLOT := SLOT^.NEXT_SLOT;
- END (*WHILE*);
- (***************** End of LOCATE_CIRC (1) ******************)
-
- STUB^.VISITED := FALSE;
- END (*IF*);
- END (*WITH*);
- MYEXIT:
- (***************** End of LOCATE_CIRC (body) *******************)
- END (*PROCEDURE LOCATE_CIRC*);
- (***************** End of procedure LOCATE_CIRC ********************)
-
- BEGIN
- SHADOW_STUB := LIST_HEAD;
- WHILE SHADOW_STUB <> NIL DO
- BEGIN
- MAIN_STUB := NIL;
-
- WITH SHADOW_STUB^.STUB_POINTER^ DO
- BEGIN
- IF NOT SP_IS_EMPTY_STR (OPTIONS.FILE_NAME) THEN
- MAIN_STUB := SHADOW_STUB^.STUB_POINTER;
- END (*WITH*);
-
- IF MAIN_STUB <> NIL THEN
- BEGIN
- STUB := CODE_STRUCT.FIRST_STUB;
- WHILE STUB <> NIL DO
- BEGIN
- STUB^.VISITED := FALSE;
- STUB := STUB^.NEXT_STUB;
- END (*WHILE*);
-
- CIRCULARITY := FALSE;
- REMOVED := FALSE;
- LOCATE_CIRC (CODE_STRUCT, MAIN_STUB, CIRCULARITY, REMOVED);
- END (*IF*);
- SHADOW_STUB := SHADOW_STUB^.NEXT;
- END (*WHILE*)
- END (*PROCEDURE CHECK_CIRC*);
-
-
- (*********************************************************************)
- (* Routine: ORDER_TWINS - ORDER TWIN stub chains. *)
- (* Purpose: To (re)order the chains of twin stubs. *)
- (* Interface: SHADOW_LIST: The list of pointers to the first *)
- (* elements of the twin stub chain. *)
- (* CODE_STRUCT: Structure of stubs and slots. *)
- (* LIST_HEAD: Pointer to first element of the *)
- (* shadow_list. *)
- (*********************************************************************)
- PROCEDURE ORDER_TWINS (VAR SHADOW_LIST: SHADOW_LIST_;
- VAR CODE_STRUCT: CODE_STRUCT_;
- VAR LIST_HEAD: SHADOW_PTR_);
-
- VAR
- FIRST_TWIN: STB_PTR_;
- SHADOW_STUB: SHADOW_PTR_;
- PREV_SHADOW_STUB: SHADOW_PTR_;
- TWIN_STUB: STB_PTR_;
- PREV_TWIN: STB_PTR_;
- CONTINUE: BOOLEAN;
- LAST_TWIN: STB_PTR_;
- SEPARATOR_STUB: STB_PTR_;
- STUB_WALKER: STB_PTR_;
- HELP_STUB: STB_PTR_;
- ERROR: BOOLEAN;
- DUMMY_LINE: LINE_DES_;
- STRING132: STRING132_;
-
- BEGIN
- (********************* ORDER_TWINS body ************************)
- PREV_SHADOW_STUB := NIL;
- SHADOW_STUB := LIST_HEAD;
- WHILE SHADOW_STUB <> NIL DO
- BEGIN
- FIRST_TWIN := SHADOW_STUB^.STUB_POINTER;
-
- (************************ ORDER_TWINS (1) *********************)
- (** Order the twin stub chain headed by FIRST_TWIN. Make sure **)
- (** that its first element remains accessible through by **)
- (** SHADOW_STUB. **)
- PREV_TWIN := NIL;
- TWIN_STUB := FIRST_TWIN;
- WHILE TWIN_STUB <> NIL DO
- BEGIN
- IF TWIN_STUB^.OPTIONS.DEFAULT THEN
- BEGIN
- (********************* ORDER_TWINS (1.1) *******************)
- (** Remove the TWIN_STUB from the list if it is no longer **)
- (** needed. Update SHADOW_LIST if needed. **)
- IF (TWIN_STUB^.NEXT_TWIN <> NIL) AND
- (PREV_TWIN = NIL)
- THEN SHADOW_STUB^.STUB_POINTER := TWIN_STUB^.NEXT_TWIN
- ELSE IF (TWIN_STUB^.NEXT_TWIN <> NIL) AND
- (PREV_TWIN <> NIL)
- THEN PREV_TWIN^.NEXT_TWIN := TWIN_STUB^.NEXT_TWIN
- ELSE IF (TWIN_STUB^.NEXT_TWIN = NIL) AND
- (PREV_TWIN <> NIL)
- THEN PREV_TWIN^.NEXT_TWIN := NIL
- ELSE
- BEGIN
- (* Nothing remains to be done here. *)
- END(*IF.IF.IF*);
- (***************** End of ORDER_TWINS (1.1) ****************)
- END (*IF*);
- IF TWIN_STUB^.OPTIONS.LEADER THEN
- BEGIN
- (********************* ORDER_TWINS (1.2) *******************)
- (** Remove TWIN_STUB and put it ahead of the twin stub **)
- (** chain. Remove SHADOW_STUB from SHADOW_LIST if TWIN_STUB **)
- (** is no longer needed. **)
- IF (TWIN_STUB^.NEXT_TWIN = NIL) AND (PREV_TWIN = NIL) THEN
- BEGIN
- IF PREV_SHADOW_STUB = NIL THEN
- BEGIN
- LIST_HEAD := SHADOW_STUB^.NEXT;
- SHADOW_STUB := LIST_HEAD;
- PREV_SHADOW_STUB := NIL;
- END
- ELSE
- BEGIN
- PREV_SHADOW_STUB^.NEXT := SHADOW_STUB^.NEXT;
- SHADOW_STUB := PREV_SHADOW_STUB;
- END (*IF*);
- END
- ELSE IF (TWIN_STUB^.NEXT_TWIN <> NIL) AND (PREV_TWIN <> NIL) THEN
- BEGIN
- PREV_TWIN^.NEXT_TWIN := TWIN_STUB^.NEXT_TWIN;
- TWIN_STUB^.NEXT_TWIN := FIRST_TWIN;
- SHADOW_STUB^.STUB_POINTER := TWIN_STUB;
- TWIN_STUB := PREV_TWIN;
- FIRST_TWIN := SHADOW_STUB^.STUB_POINTER;
- END
- ELSE IF (TWIN_STUB^.NEXT_TWIN = NIL) AND (PREV_TWIN <> NIL) THEN
- BEGIN
- PREV_TWIN^.NEXT_TWIN := NIL;
- TWIN_STUB^.NEXT_TWIN := FIRST_TWIN;
- SHADOW_STUB^.STUB_POINTER := TWIN_STUB;
- TWIN_STUB := PREV_TWIN;
- FIRST_TWIN := SHADOW_STUB^.STUB_POINTER;
- END
- ELSE
- BEGIN
- (* Leader stub is in place,nothing remains to be *)
- (* done here. *)
- END (*IF.IF.IF*);
- (***************** End of ORDER_TWINS (1.2) ****************)
- END (*IF*);
- IF TWIN_STUB^.OPTIONS.TRAILER THEN
- BEGIN
- (********************* ORDER_TWINS (1.3) *******************)
- (** Remove TWIN_STUB and put it at the tail of the twin **)
- (** stub chain. **)
-
- (* Locate the last stub in the twin stub chain *)
- LAST_TWIN := TWIN_STUB;
- WHILE LAST_TWIN^.NEXT_TWIN <> NIL DO
- LAST_TWIN := LAST_TWIN^.NEXT_TWIN;
- IF (TWIN_STUB^.NEXT_TWIN = NIL) AND (PREV_TWIN = NIL) THEN
- BEGIN
- IF PREV_SHADOW_STUB = NIL THEN
- BEGIN
- LIST_HEAD := SHADOW_STUB^.NEXT;
- SHADOW_STUB := LIST_HEAD;
- PREV_SHADOW_STUB := NIL;
- END
- ELSE
- BEGIN
- PREV_SHADOW_STUB^.NEXT := SHADOW_STUB^.NEXT;
- SHADOW_STUB := PREV_SHADOW_STUB;
- END (*IF*);
- END
- ELSE IF (TWIN_STUB^.NEXT_TWIN <> NIL) AND (PREV_TWIN <> NIL) THEN
- BEGIN
- PREV_TWIN^.NEXT_TWIN := TWIN_STUB^.NEXT_TWIN;
- LAST_TWIN^.NEXT_TWIN := TWIN_STUB;
- LAST_TWIN := LAST_TWIN^.NEXT_TWIN;
- LAST_TWIN^.NEXT_TWIN := NIL;
- TWIN_STUB := PREV_TWIN;
- END
- ELSE IF (TWIN_STUB^.NEXT_TWIN <> NIL) AND (PREV_TWIN = NIL) THEN
- BEGIN
- SHADOW_STUB^.STUB_POINTER := TWIN_STUB^.NEXT_TWIN;
- LAST_TWIN^.NEXT_TWIN := TWIN_STUB;
- LAST_TWIN := LAST_TWIN^.NEXT_TWIN;
- LAST_TWIN^.NEXT_TWIN := NIL;
- FIRST_TWIN := SHADOW_STUB^.STUB_POINTER;
- TWIN_STUB := FIRST_TWIN;
- PREV_TWIN := NIL;
- END
- ELSE
- BEGIN
- (* Trailer stub is in position. Nothing remains *)
- (* to be done. *)
- END (*IF.IF.IF*);
- (***************** End of ORDER_TWINS (1.3) ****************)
- END (*IF*);
- PREV_TWIN := TWIN_STUB;
- TWIN_STUB := TWIN_STUB^.NEXT_TWIN;
- END (*WHILE*);
- TWIN_STUB := FIRST_TWIN;
- PREV_TWIN := NIL;
- CONTINUE := TRUE;
- WHILE (TWIN_STUB^.NEXT_TWIN <> NIL) AND (CONTINUE) DO
- BEGIN
- IF TWIN_STUB^.OPTIONS.SEPARATOR THEN
- BEGIN
- (********************* ORDER_TWINS (1.4) *******************)
- (** Copy the seperator TWIN_STUB in between all other stubs **)
- (** of the twin stub chain. **)
- IF PREV_TWIN = NIL THEN
- BEGIN
- FIRST_TWIN := TWIN_STUB^.NEXT_TWIN;
- SHADOW_STUB^.STUB_POINTER := FIRST_TWIN;
- SEPARATOR_STUB := TWIN_STUB;
- END
- ELSE
- BEGIN
- PREV_TWIN^.NEXT_TWIN := TWIN_STUB^.NEXT_TWIN;
- SEPARATOR_STUB := TWIN_STUB;
- TWIN_STUB := PREV_TWIN;
- END (*IF*);
- STUB_WALKER := FIRST_TWIN;
- WHILE STUB_WALKER^.NEXT_TWIN <> NIL DO
- BEGIN
- HELP_STUB := STUB_WALKER^.NEXT_TWIN;
- NEW (STUB_WALKER^.NEXT_TWIN);
- STUB_WALKER := STUB_WALKER^.NEXT_TWIN;
- STUB_WALKER^ := SEPARATOR_STUB^;
- STUB_WALKER^.NEXT_TWIN := HELP_STUB;
- STUB_WALKER := HELP_STUB;
- END (*WHILE*);
- (***************** End of ORDER_TWINS (1.4) ****************)
-
- CONTINUE := FALSE;
- END (*IF*);
- PREV_TWIN := TWIN_STUB;
- TWIN_STUB := TWIN_STUB^.NEXT_TWIN;
- END (*WHILE*);
-
- (************************* ORDER_TWINS (1.5) ***********************)
- (** Examine the twin stub chain accessible by FIRST_TWIN. Generate **)
- (** a diagnostic message in case the chain contains only LEADER, **)
- (** SEPARATOR and TRAILER stubs. **)
- ERROR := TRUE;
- STUB_WALKER := FIRST_TWIN;
- WHILE (STUB_WALKER <> NIL) AND (ERROR = TRUE) DO
- BEGIN
- IF (NOT STUB_WALKER^.OPTIONS.LEADER) AND
- (NOT STUB_WALKER^.OPTIONS.SEPARATOR) AND
- (NOT STUB_WALKER^.OPTIONS.TRAILER) THEN
- ERROR := FALSE;
- STUB_WALKER := STUB_WALKER^.NEXT_TWIN;
- END (*WHILE*);
- IF (STUB_WALKER = NIL) AND (ERROR) THEN
- BEGIN
- STRING132.LENGTH := 0;
- STRING132.BODY := EMPTY_STRING_FIXED;
- FT_INIT_LINE (DUMMY_LINE);
- DIAG(WARN, 'ORDER_TWINS (1.5) ', DUMMY_LINE,
- FIRST_TWIN^.SRC_IMG, STRING132);
- IF PREV_SHADOW_STUB = NIL THEN
- BEGIN
- LIST_HEAD := SHADOW_STUB^.NEXT;
- SHADOW_STUB := LIST_HEAD;
- PREV_SHADOW_STUB := NIL;
- END
- ELSE
- BEGIN
- PREV_SHADOW_STUB^.NEXT := SHADOW_STUB^.NEXT;
- SHADOW_STUB := PREV_SHADOW_STUB;
- END (*IF*);
- END
- ELSE
- BEGIN
- (* The twin stub chain is ok and nothing remains to be *)
- (* done here. *)
- END (*IF*);
- (********************* End of ORDER_TWINS (1.5) ********************)
-
- (********************* End of ORDER_TWINS (1) ******************)
-
- PREV_SHADOW_STUB := SHADOW_STUB;
- SHADOW_STUB := SHADOW_STUB^.NEXT;
- END (*WHILE*);
- (***************** End of ORDER_TWINS (body) *******************)
- END (*PROCEDURE ORDER_TWINS*);
-
-
- (*********************************************************************)
- (* Routine: ANALYSE - ANALYSEr phase *)
- (* Purpose: To analyse the structure of stubs and slots. *)
- (* Interface: Input: CODE_STRUCT - the structure to be analyzed. *)
- (* Output: CODE_STRUCT - the analyzed structure. *)
- (*********************************************************************)
- PROCEDURE ANALYSE (VAR CODE_STRUCT: CODE_STRUCT_);
-
- VAR
- SHADOW_LIST: SHADOW_LIST_;
- LIST_HEAD: SHADOW_PTR_;
- STRING132: STRING132_;
- LAST_SHADOW: SHADOW_PTR_;
- STUB: STB_PTR_;
- LOCATED: BOOLEAN;
- SHADOW_STUB: SHADOW_PTR_;
- CANDIDATE_TWIN: STB_PTR_;
- SLOT: SLT_PTR_;
- STUB_REF: STB_PTR_;
- DUMMY_LINE: LINE_DES_;
-
- BEGIN
- (********************* ANALYSE body ****************************)
-
- LIST_HEAD := NIL;
-
- (************************* ANALYSE (1) *************************)
- (** Build SHADOW_LIST from the stub chain of CODE_STRUCT. Make **)
- (** first element of SHADOW_LIST accessible by LIST_HEAD **)
- STUB := CODE_STRUCT.FIRST_STUB;
- IF STUB <> NIL THEN
- BEGIN
- NEW (LIST_HEAD);
- LAST_SHADOW := LIST_HEAD;
- LAST_SHADOW^.NEXT := NIL;
- LAST_SHADOW^.STUB_POINTER := STUB;
- STUB := STUB^.NEXT_STUB;
- WHILE STUB <> NIL DO
- BEGIN
- (********************* ANALYSE (1.1) ***********************)
- (** Check if STUB^.NAME is already linked in SHADOW_LIST. **)
- (** If not, make a new entry for this stub in SHADOW_LIST **)
- (** and update LAST_SHADOW. **)
- IF SP_IS_EMPTY_STR (STUB^.NAME) THEN
- LOCATED := FALSE
- ELSE
- BEGIN
- SHADOW_STUB := LIST_HEAD;
- LOCATED := FALSE;
- WHILE (NOT LOCATED) AND (SHADOW_STUB <> NIL) DO
- BEGIN
- IF SP_EQ (SHADOW_STUB^.STUB_POINTER^.NAME, STUB^.NAME) THEN
- LOCATED := TRUE;
- SHADOW_STUB := SHADOW_STUB^.NEXT;
- END (*WHILE*);
- END (*IF*);
- IF NOT LOCATED THEN
- BEGIN
- NEW (LAST_SHADOW^.NEXT);
- LAST_SHADOW := LAST_SHADOW^.NEXT;
- LAST_SHADOW^.STUB_POINTER := STUB;
- LAST_SHADOW^.NEXT := NIL;
- END (*IF*);
- (***************** End of ANALYSE (1.1) ********************)
-
- STUB := STUB^.NEXT_STUB;
- END (*WHILE*);
- END (*IF*);
- (************************* End of ANALYSE (1) **********************)
-
- IF LIST_HEAD <> NIL THEN
- BEGIN
- (************************ ANALYSE (2) **********************)
- (** Link stubs with identical names into a twin stub chain **)
- (** using NEXT_TWIN of the stub descriptor. Start each twin **)
- (** stub chain with the stub accessible by SHADOW_LIST. **)
- SHADOW_STUB := LIST_HEAD;
- WHILE SHADOW_STUB <> NIL DO
- BEGIN
- STUB := SHADOW_STUB^.STUB_POINTER;
- IF NOT SP_IS_EMPTY_STR(STUB^.NAME) THEN
- WHILE STUB <> NIL DO
- BEGIN
- (***************** ANALYSE (2.1) *******************)
- (** Read through the list of stubs starting with **)
- (** STUB and set STUB^.NEXT_TWIN if a stub with **)
- (** the same name as STUB^.NAME found. Let **)
- (** CANDIDATE_TWIN refer to this stub. **)
- LOCATED := FALSE;
- CANDIDATE_TWIN := STUB^.NEXT_STUB;
- WHILE (CANDIDATE_TWIN <> NIL) AND (NOT LOCATED) DO
- BEGIN
- IF SP_EQ (STUB^.NAME, CANDIDATE_TWIN^.NAME) THEN
- BEGIN
- LOCATED := TRUE;
- STUB^.NEXT_TWIN := CANDIDATE_TWIN;
- END
- ELSE
- CANDIDATE_TWIN := CANDIDATE_TWIN^.NEXT_STUB;
- END (*WHILE*);
- (************* End of ANALYSE (2.1) ****************)
-
- STUB := CANDIDATE_TWIN;
- END (*WHILE*);
- SHADOW_STUB := SHADOW_STUB^.NEXT;
- END (*WHILE*);
- (********************* End of ANALYSE (2) ******************)
-
- (********************* ANALYSE (3) *************************)
- (** Reorder the twin stub chain by using the options of **)
- (** the stub. SHADOW_LIST.STUB_POINTER must always refer to **)
- (** the first stub of the twin stub chain. **)
-
- ORDER_TWINS (SHADOW_LIST, CODE_STRUCT, LIST_HEAD);
-
- (***************** End of ANALYSE (3) **********************)
-
- (********************* ANALYSE (4) *************************)
- (** Update the field STUB_REF of the slots in the structure **)
- (** by searching a stub with the same name as the slot in **)
- (** the structure. Use SHADOW_LIST to access the stubs. **)
- (** Check if the option SLOT^.OPTIONS.MULTIPLE is used **)
- (** correctly. Use SLOT^.SRC_IMG for diagnostics. **)
- STUB := CODE_STRUCT.FIRST_STUB;
- WHILE STUB <> NIL DO
- BEGIN
- SLOT := STUB^.SLOTS;
- WHILE SLOT <> NIL DO
- BEGIN
- (***************** ANALYSE (4.1) *******************)
- (** Use SHADOW_LIST to search a stub with the same **)
- (** name as SLOT^.NAME and update SLOT^.STUB_REF if **)
- (** such a stub is found. SLOT^.SRC_IMG serves for **)
- (** a diagnostic if multiple stubs are used in a **)
- (** slot without the MULTIPLE-option **)
- LOCATED := FALSE;
- SHADOW_STUB := LIST_HEAD;
- WHILE (SHADOW_STUB <> NIL) AND
- (NOT LOCATED) AND
- (NOT SP_IS_EMPTY_STR(SLOT^.NAME)) DO
- BEGIN
- STUB_REF := SHADOW_STUB^.STUB_POINTER;
- IF SP_EQ (STUB_REF^.NAME, SLOT^.NAME) THEN
- BEGIN
- LOCATED := TRUE;
- SLOT^.STUB_REF := STUB_REF;
- IF NOT SLOT^.OPTIONS.MULTIPLE THEN
- BEGIN
- IF STUB_REF^.NEXT_TWIN <> NIL THEN
- BEGIN
- STRING132.LENGTH := 0;
- STRING132.BODY := EMPTY_STRING_FIXED;
- FT_INIT_LINE (DUMMY_LINE);
- DIAG (ERR, 'ANALYSE (4.1) ', DUMMY_LINE,
- SLOT^.SRC_IMG, STRING132);
- SLOT^.OPTIONS.MULTIPLE := TRUE;
- END (*IF*);
- END (*IF*);
- END
- ELSE
- SHADOW_STUB := SHADOW_STUB^.NEXT;
- END (*WHILE*);
- (************* End of ANALYSE (4.1) ****************)
-
- SLOT := SLOT^.NEXT_SLOT;
- END (*WHILE*);
- STUB := STUB^.NEXT_STUB;
- END (*WHILE*);
- (********************* End of ANALYSE (4) ******************)
-
- (********************* ANALYSE (5) *************************)
- (** Check the resulting structure of CODE_STRUCT for **)
- (** circularity. If circularity is detected, break the **)
- (** responsible chain and generate a diagnostic. **)
-
- CHECK_CIRC (CODE_STRUCT, LIST_HEAD);
-
- (********************* End of ANALYSE (5) ******************)
- END (*IF*)
- (********************* End of ANALYSE body *********************)
- END (*PROCEDURE ANALYSE*);
-
-
- (*********************************************************************)
- (* Routine: GENMOD - MODule GENeration phase *)
- (* Purpose: Generation of modules out of CODE_STRUCT. *)
- (* Interface: CODE_STRUCT - Representation of the stub and slot *)
- (* structure. *)
- (* RUN_INFO: User's information for this run. *)
- (*********************************************************************)
- PROCEDURE GENMOD (CODE_STRUCT: CODE_STRUCT_; RUN_INFO: RUN_INFO_);
-
- VAR
- STB_PTR: STB_PTR_;
- CONTINUE: BOOLEAN;
- LOCATED: BOOLEAN;
- OUT_FILE: TEXT;
- NR_OPEN_SLOTS,
- NR_LINES,
- CORRECTION,
- INDENT: INTEGER;
- AUX_STRING_132 : STRING_FIXED_;
- AUX_STRING_9 : PACKED ARRAY[1..9] OF CHAR;
- EXTRACTED: BOOLEAN;
- CH1, CH2: CHAR;
- I: INTEGER;
- MODULE_NR: INTEGER;
- ERROR_CODE: ERROR_CODE_;
- X: INTEGER;
- TEMP_FILE_SPEC: STRING132_;
- REAL_FILE_SPEC: FILE_SPEC_;
- DUMMY_LINE: LINE_DES_;
- STRING132: STRING132_;
-
- (************************* GENMOD routines *************************)
-
- (*********************************************************************)
- (* Procedure: BUILDER - BUILDER of module. *)
- (* Purpose: Build one single module. *)
- (* Interface: STUB - Pointer to the starting point of the *)
- (* structure. *)
- (* OUT_FILE - File to accept the generated code. *)
- (* NR_OPEN_SLOTS - Number of open slots when ready. *)
- (* NR_LINES - Number of generated code lines. *)
- (* INDENT - Current indentation level. *)
- (* CORRECTION - Correction value for indentation. *)
- (*********************************************************************)
- PROCEDURE BUILDER (STUB: STB_PTR_;
- VAR OUT_FILE: TEXT; VAR NR_OPEN_SLOTS: INTEGER;
- VAR NR_LINES: INTEGER; VAR INDENT: INTEGER;
- VAR CORRECTION: INTEGER);
-
- VAR
- PREV_INDENT: INTEGER;
- TWIN_STUB: STB_PTR_;
- SLOT: SLT_PTR_;
- FIRST,
- LAST: INTEGER;
- INFO_LINE: LINE_DES_;
- SEG_LENGTH: INTEGER;
- STRING132: STRING132_;
- FILE_SPEC: FILE_SPEC_;
- K: INTEGER;
- DUMMY_FILE:
- VARYING
- [80]
- OF CHAR;
- DUMMY:
- VARYING
- [132]
- OF CHAR;
-
- BEGIN
- (********************* BUILDER (body) **************************)
- WITH STUB^ DO
- BEGIN
- CORRECTION := ST_GET_INDENT (STUB^.SRC_IMG);
- INDENT := INDENT-CORRECTION;
- IF STUB^.OPTIONS.LINENUMBER THEN
- BEGIN
- (************************* BUILDER (1) *********************)
- (** Use INDENT to write file specification and line number **)
- (** of the source file from which STUB^.SRC_IMG is extrac- **)
- (** ted to OUT_FILE. **)
- ST_GET_SEG_RANGE (STUB^.SRC_IMG, FIRST, LAST);
- ST_GET_FILE_SPEC (STUB^.SRC_IMG, FILE_SPEC);
- FT_INIT_LINE (INFO_LINE);
- INFO_LINE.INDENT := ST_GET_INDENT (STUB^.SRC_IMG); (* !!! *)
- DUMMY_FILE := '';
- FOR K := 1 TO FILE_SPEC.LENGTH DO
- DUMMY_FILE := DUMMY_FILE + FILE_SPEC.BODY[K];
- DUMMY := '';
- WRITE (DUMMY, '(** Line: ', FIRST:1, ' File: ',
- DUMMY_FILE); (* ISO vreemd *)
- SEG_LENGTH := ST_SEG_WIDTH (STUB^.SRC_IMG);
- FOR K := LENGTH(DUMMY) TO (SEG_LENGTH - 4) DO
- DUMMY := DUMMY + ' ';
- DUMMY := DUMMY + '**)';
- FOR K := 1 TO LENGTH(DUMMY) DO
- INFO_LINE.CHARS[K] := DUMMY[K]; (* !!! *)
- INFO_LINE.USED := LENGTH(DUMMY); (* !!! *)
- SP_EXTR_STR (STUB^.OPTIONS.INDENT, STRING132);
- IF (STRING132.BODY[1] = 'O') AND (STRING132.BODY[2] = 'N') THEN
- FT_WRLN (INFO_LINE, INDENT,1)
- ELSE
- FT_WRLN (INFO_LINE, 0, 1);
- (********************* End of BUILDER (1) ******************)
-
- NR_LINES := NR_LINES+1;
- END (*IF*);
-
- (************************* BUILDER (2) *************************)
- (** Use OPTIONS.COMMENT to decide if STUB^.SRC_IMG needs to be **)
- (** written to OUT_FILE. If so, then increase NR_LINES accor- **)
- (** dingly and use INDENT to position the segment. **)
- SP_EXTR_STR (STUB^.OPTIONS.COMMENT, STRING132);
- IF (STRING132.BODY[1] = 'O') AND (STRING132.BODY[2] = 'N') THEN
- BEGIN
- SP_EXTR_STR (STUB^.OPTIONS.INDENT, STRING132);
- IF (STRING132.BODY[1] = 'O') AND (STRING132.BODY[2] = 'N') THEN
- ST_WRITE_SEG (STUB^.SRC_IMG,INDENT,1)
- ELSE
- ST_WRITE_SEG (STUB^.SRC_IMG,0,1);
- NR_LINES := NR_LINES + ST_NUMBER_OF_LINES (STUB^.SRC_IMG);
- END (*IF*);
- (********************* End of BUILDER (2) **********************)
-
- SLOT := STUB^.SLOTS;
- WHILE SLOT <> NIL DO
- BEGIN
- (************************* BUILDER (3) *********************)
- (** SLOT inherits the options INDENT and COMMENT from STUB **)
- (** when they are not redefined. SLOT also inherits STUB^.- **)
- (** OPTIONS.LINENUMBER. **)
- IF SP_IS_EMPTY_STR (SLOT^.OPTIONS.INDENT) THEN
- SLOT^.OPTIONS.INDENT := STUB^.OPTIONS.INDENT;
- IF SP_IS_EMPTY_STR (SLOT^.OPTIONS.COMMENT) THEN
- SLOT^.OPTIONS.COMMENT := STUB^.OPTIONS.COMMENT;
- SLOT^.OPTIONS.LINENUMBER := STUB^.OPTIONS.LINENUMBER;
- (********************* End of BUILDER (3) ******************)
-
- IF SLOT^.STUB_REF = NIL THEN
- BEGIN
- (********************* BUILDER (4) *********************)
- (** SLOT has no reference to a stub. Write segments **)
- (** SLOT^.SRC_IMG and SLOT^.CODE to OUT_FILE using **)
- (** COMMENT and INDENT. Update NR_LINES accodingly. **)
- WITH SLOT^ DO
- BEGIN
- SP_EXTR_STR (STUB^.OPTIONS.COMMENT, STRING132);
- IF (STRING132.BODY[1] = 'O') AND (STRING132.BODY[2] = 'N') THEN
- BEGIN
- SP_EXTR_STR (SLOT^.OPTIONS.INDENT, STRING132);
- IF (STRING132.BODY[1] = 'O') AND (STRING132.BODY[2] = 'N') THEN
- ST_WRITE_SEG (SLOT^.SRC_IMG,INDENT,1)
- ELSE
- ST_WRITE_SEG (SLOT^.SRC_IMG, 0, 1);
- NR_LINES := NR_LINES + ST_NUMBER_OF_LINES (SLOT^.SRC_IMG);
- END (*IF*);
- SP_EXTR_STR (SLOT^.OPTIONS.INDENT, STRING132);
- IF (STRING132.BODY[1] = 'O') AND (STRING132.BODY[2] = 'N') THEN
- ST_WRITE_SEG (CODE,INDENT,1)
- ELSE
- ST_WRITE_SEG (CODE, 0, 1);
- NR_LINES := NR_LINES + ST_NUMBER_OF_LINES (SLOT^.CODE);
- END(*WITH*);
- (***************** End of BUILDER (4) ******************)
-
- IF (SLOT^.NEXT_SLOT <> NIL) AND
- (NOT SP_IS_EMPTY_STR(SLOT^.NAME)) AND
- (NOT SLOT^.OPTIONS.OPTIONAL) THEN
- BEGIN
- IF NR_OPEN_SLOTS = 0 THEN
- BEGIN
- WRITELN ('The following open slots are found:');
- WRITELN;
-
- IF REPORT_OK THEN
- BEGIN
- WRITELN (REPORT_FILE,
- 'The following open slots are found:');
- WRITELN (REPORT_FILE);
- END (*IF*);
- END (*IF*);
-
- (* Write slot to terminal and to output file. *)
- ST_WRITE_SEG (SLOT^.SRC_IMG, INDENT, 0);
- WRITELN;
-
- IF REPORT_OK THEN
- BEGIN
- ST_WRITE_SEG (SLOT^.SRC_IMG, INDENT, 3);
- WRITELN (REPORT_FILE);
- END (*IF*);
-
- NR_OPEN_SLOTS := NR_OPEN_SLOTS+1;
- END (*IF*);
- END
- ELSE
- BEGIN
- (********************* BUILDER (5) *********************)
- (** SLOT^.STUB_REF inherits the options INDENT and **)
- (** COMMENT from SLOT if they are not redefined by **)
- (** SLOT^.STUB_REF. SLOT^.STUB_REF also inherits **)
- (** LINENUMBER from SLOT. **)
- IF SP_IS_EMPTY_STR (SLOT^.STUB_REF^.OPTIONS.INDENT) THEN
- SLOT^.STUB_REF^.OPTIONS.INDENT := SLOT^.OPTIONS.INDENT;
- IF SP_IS_EMPTY_STR (SLOT^.STUB_REF^.OPTIONS.COMMENT) THEN
- SLOT^.STUB_REF^.OPTIONS.COMMENT := SLOT^.OPTIONS.COMMENT;
- SLOT^.STUB_REF^.OPTIONS.LINENUMBER := SLOT^.OPTIONS.LINENUMBER;
- (***************** End of BUILDER (5) ******************)
-
- PREV_INDENT := INDENT;
- INDENT := INDENT + ST_GET_INDENT (SLOT^.SRC_IMG);
- BUILDER (SLOT^.STUB_REF, OUT_FILE, NR_OPEN_SLOTS,
- NR_LINES, INDENT, CORRECTION);
- TWIN_STUB := SLOT^.STUB_REF^.NEXT_TWIN;
- WHILE TWIN_STUB <> NIL DO
- BEGIN
- (********************* BUILDER (6) *****************)
- (** TWIN_STUB inherits INDENT and COMMENT from **)
- (** SLOT when they are not redefined locally. In **)
- (** addition TWIN_STUB inherits LINENUMBER from **)
- (** SLOT. **)
- IF SP_IS_EMPTY_STR (TWIN_STUB^.OPTIONS.INDENT) THEN
- TWIN_STUB^.OPTIONS.INDENT := SLOT^.OPTIONS.INDENT;
- IF SP_IS_EMPTY_STR (TWIN_STUB^.OPTIONS.COMMENT) THEN
- TWIN_STUB^.OPTIONS.COMMENT := SLOT^.OPTIONS.COMMENT;
- TWIN_STUB^.OPTIONS.LINENUMBER := SLOT^.OPTIONS.LINENUMBER;
- (***************** End of BUILDER (6) **************)
-
- INDENT := ST_GET_INDENT (SLOT^.SRC_IMG);
- BUILDER (TWIN_STUB, OUT_FILE, NR_OPEN_SLOTS,
- NR_LINES, INDENT, CORRECTION);
- TWIN_STUB := TWIN_STUB^.NEXT_TWIN;
- END (*WHILE*);
- INDENT := PREV_INDENT;
-
- (********************* BUILDER (7) *********************)
- (** Write the segment SLOT^.CODE to OUT_FILE using the **)
- (** option SLOT^.INDENT. **)
- SP_EXTR_STR (SLOT^.OPTIONS.INDENT, STRING132);
- IF (STRING132.BODY[1] = 'O') AND
- (STRING132.BODY[2] = 'F') AND
- (STRING132.BODY[3] = 'F') THEN
- ST_WRITE_SEG (SLOT^.CODE, 0, 1)
- ELSE
- ST_WRITE_SEG (SLOT^.CODE,INDENT,1);
- (***************** End of BUILDER (7) ******************)
-
- NR_LINES := NR_LINES + ST_NUMBER_OF_LINES (SLOT^.CODE);
- END (*IF*);
- SLOT := SLOT^.NEXT_SLOT;
- END (*WHILE*);
- END (*WITH*);
- (********************* End of BUILDER (body) *******************)
- END (*PROCEDURE BUILDER*);
-
- (********************* End of GENMOD routines **********************)
-
- BEGIN
- (********************* GENMOD (body) ***************************)
- AUX_STRING_9 := 'EXTRACTED';
- AUX_STRING_132 := EMPTY_STRING_FIXED;
- FOR I:= 1 TO 9 DO
- AUX_STRING_132[I] := AUX_STRING_9[I];
- IF (RUN_INFO.EXTR_MODE <> AUX_STRING_132) THEN
- EXTRACTED := FALSE
- ELSE
- EXTRACTED := TRUE;
-
- STB_PTR := CODE_STRUCT.FIRST_STUB;
- WHILE STB_PTR <> NIL DO
- BEGIN
- LOCATED := FALSE;
- WHILE (STB_PTR <> NIL) AND (NOT LOCATED) DO
- BEGIN
- (************************* GENMOD (1) **********************)
- (** If STB_PTR refers to a main stub then use RUN_INFO to **)
- (** check if the module is desired by the user. Raise **)
- (** LOCATED if this happens to be the case. **)
- WITH STB_PTR^ DO
- BEGIN
- IF NOT SP_IS_EMPTY_STR (OPTIONS.FILE_NAME) THEN
- BEGIN
- (********************* GENMOD (1.1) ************************)
- (** Use RUN_INFO to check if OPTIONS.FILE_NAME indicates a **)
- (** module that is wanted by the user. Raise LOCATED if **)
- (** this is the case. Default the options COMMENT and **)
- (** INDENT it they have not been set explictely. **)
- WITH RUN_INFO DO
- BEGIN
- CH1 := 'O';
- CH2 := 'N';
- IF SP_IS_EMPTY_STR (OPTIONS.INDENT) THEN
- BEGIN
- SP_ADD_CHAR (CH1,OPTIONS.INDENT);
- SP_ADD_CHAR (CH2,OPTIONS.INDENT);
- END (*IF*);
- IF SP_IS_EMPTY_STR (OPTIONS.COMMENT) THEN
- BEGIN
- SP_ADD_CHAR (CH1,OPTIONS.COMMENT);
- SP_ADD_CHAR (CH2,OPTIONS.COMMENT);
- END (*IF*);
- SP_EXTR_STR (STB_PTR^.OPTIONS.FILE_NAME, TEMP_FILE_SPEC);
- LOCATED := FALSE;
- FOR X := 1 TO RUN_INFO.NR_MODULES DO
- BEGIN
- IF TEMP_FILE_SPEC.BODY=
- RUN_INFO.RSLT_MODULES[X].FILE_NAME.BODY THEN
- BEGIN
- LOCATED := TRUE;
- MODULE_NR := X;
- END (*IF*);
- END (*FOR*);
-
- (* Use the value of EXTRACTED to decide *)
- (* whether the module is wanted or not. *)
- IF EXTRACTED = FALSE THEN LOCATED := NOT LOCATED;
- END (*WITH*);
- (***************** End of GENMOD (1.1) *********************)
- END (*IF*);
- END (*WITH*);
- (********************* End of GENMOD (1) *******************)
-
- IF NOT LOCATED THEN
- STB_PTR := STB_PTR^.NEXT_STUB;
- END (*WHILE*);
- IF LOCATED THEN
- BEGIN
- CONTINUE := TRUE;
-
- (************************* GENMOD (2) **********************)
- (** Open OUT_FILE with a name specified by this main stub. **)
- (** Set CONTINUE to FALSE if there is a problem. STB_PTR^.- **)
- (** OPTIONS.FILE_NAME caused the problem and displayed as **)
- (** part of an error message. **)
-
- SP_EXTR_STR (STB_PTR^.OPTIONS.FILE_NAME, TEMP_FILE_SPEC);
-
- (* The type of TEMP_FILE_SPEC is not suitable for the File Table *)
- (* routine which opens files. It is converted to a REAL_FILE_SPEC. *)
-
- REAL_FILE_SPEC.BODY := EMPTY_STRING_FIXED;
- REAL_FILE_SPEC.LENGTH := 0;
-
- IF EXTRACTED THEN
- BEGIN
- FOR I:= 1 TO RUN_INFO.RSLT_MODULES[MODULE_NR].PATH.LENGTH DO
- REAL_FILE_SPEC.BODY[I] :=
- RUN_INFO.RSLT_MODULES[MODULE_NR].PATH.BODY[I];
- REAL_FILE_SPEC.LENGTH := RUN_INFO.RSLT_MODULES[MODULE_NR].PATH.LENGTH;
- END
- ELSE
- BEGIN
- FOR I:= 1 TO RUN_INFO.MODULE_DIRECTORY.LENGTH DO
- REAL_FILE_SPEC.BODY[I] := RUN_INFO.MODULE_DIRECTORY.BODY[I];
- REAL_FILE_SPEC.LENGTH := RUN_INFO.MODULE_DIRECTORY.LENGTH;
- END; (*IF*)
-
- X := REAL_FILE_SPEC.LENGTH;
- I := 1;
- WHILE I <= TEMP_FILE_SPEC.LENGTH DO
- BEGIN
- X:=X+1;
- REAL_FILE_SPEC.BODY[X] := TEMP_FILE_SPEC.BODY[I];
- I:=I+1;
- END (*WHILE*);
- REAL_FILE_SPEC.LENGTH := X;
-
- ERROR_CODE := FT_OUTOPEN (REAL_FILE_SPEC);
- IF ERROR_CODE > 0 THEN
- BEGIN
- CONTINUE := FALSE;
-
- (********************* GENMOD (2.1) ****************************)
- (** Use STB_PTR^.OPTIONS.FILE_NAME and the returned ERROR_CODE **)
- (** to generate an error message. **)
- FT_INIT_LINE (DUMMY_LINE);
- SP_EXTR_STR (STB_PTR^.OPTIONS.FILE_NAME, STRING132);
- DIAG (ERR, 'GENMOD (2.1) ', DUMMY_LINE,
- STB_PTR^.SRC_IMG, STRING132);
- (********************* End of GENMOD (2.1) *********************)
- END (*IF*);
- (********************* End of GENMOD (2) *******************)
-
- IF CONTINUE THEN
- BEGIN
- NR_OPEN_SLOTS := 0;
- NR_LINES := 0;
-
- (********************* GENMOD (3) **********************)
- (** Generate the module indicated by STB_PTR into **)
- (** OUT_FILE. NR_OPEN_SLOTS and NR_LINES are maintained **)
- (** as statistical data. **)
- WRITE ('Generating file: ');
- FOR X := 1 TO REAL_FILE_SPEC.LENGTH DO
- WRITE (REAL_FILE_SPEC.BODY[X]);
- WRITELN;
-
- IF REPORT_OK THEN
- BEGIN
- WRITE (REPORT_FILE, 'Generating file: ');
- FOR X := 1 TO REAL_FILE_SPEC.LENGTH DO
- WRITE (REPORT_FILE, REAL_FILE_SPEC.BODY[X]);
- WRITELN (REPORT_FILE);
- END (*IF*);
-
- INDENT := ST_GET_INDENT (STB_PTR^.SRC_IMG);
- CORRECTION := 0;
- NR_LINES := 0;
- NR_OPEN_SLOTS := 0;
- BUILDER (STB_PTR, OUT_FILE, NR_OPEN_SLOTS, NR_LINES,
- INDENT, CORRECTION);
- (******************* End of GENMOD (3) *****************)
-
- WRITELN ('Number of open slots in this module: ',
- NR_OPEN_SLOTS:1);
- WRITELN ('Number of generated lines: ',NR_LINES:1);
-
- WRITELN ('------------------------------------',
- '------------------------------------');
- WRITELN;
-
- IF REPORT_OK THEN
- BEGIN
- WRITELN (REPORT_FILE, 'Number of open slots',
- ' in this module: ', NR_OPEN_SLOTS:1);
- WRITELN (REPORT_FILE, 'Number of generated lines: '
- ,NR_LINES:1);
- WRITELN (REPORT_FILE,
- '------------------------------------',
- '------------------------------------');
- WRITELN (REPORT_FILE);
- END (*IF*);
-
- (********************* GENMOD (4) **********************)
- (** Close OUT_FILE. Generate an error message in case **)
- (** of trouble. **)
- ERROR_CODE := FT_OUTCLOSE;
- IF ERROR_CODE <> 0 THEN
- BEGIN
- (************************* GENMOD (4.1) ************************)
- (** Use STB_PTR^.OPTIONS.FILE_NAME and STB_PTR^.SRC_IMG to **)
- (** generate a diagnostic message. **)
- FT_INIT_LINE (DUMMY_LINE);
- SP_EXTR_STR (STB_PTR^.OPTIONS.FILE_NAME, STRING132);
- DIAG (ERR, 'GENMOD (4.1) ', DUMMY_LINE,
- STB_PTR^.SRC_IMG, STRING132);
- (********************* End of GENMOD (4.1) *********************)
- END(*IF*);
- (***************** End of GENMOD (4) *******************)
- END (*IF*);
- STB_PTR := STB_PTR^.NEXT_STUB;
- END (*IF*);
- END (*WHILE*);
- (********************* End of GENMOD (body) ********************)
-
- END (*GENMOD*);
-
-
-
- BEGIN
- (******* CLIP_2 (body) *******)
- CONTINUE := TRUE;
-
- (***************************** CLIP_2 (1) **************************)
- (** Read the contents of CLIP.INI into RUN_INFO. Set CONTINUE to **)
- (** FALSE in case of trouble. **)
- EXT_FILE_SPEC.BODY := EMPTY_STRING_FIXED;
- AUX_STRING_8 := DFLT_INIFILE;
- FOR I := 1 TO 8 DO
- EXT_FILE_SPEC.BODY[I] := AUX_STRING_8[I];
- EXT_FILE_SPEC.LENGTH := 8;
- EXT_FILE_PREP (INI_FILE, EXT_FILE_SPEC, INSP_MODE, DUMMY_FILE_OK,
- ERROR_CODE, DUMMY_ERROR_MSG);
- IF ERROR_CODE > 0 THEN
- BEGIN
- WRITELN ('The initializationfile could not be read succesfully.');
- CONTINUE := FALSE;
- END
- ELSE
- BEGIN (* EWvA: 16/10/93 *)
- EXT_FILE_CLOSE (INI_FILE, DUMMY_ERROR_CODE); (* EWvA: 16/10/93 *)
- READ_INI_FILE (INI_FILE, RUN_INFO, EXT_FILE_SPEC, DUMMY_FILE_OK,
- DUMMY_ERROR_MSG, DUMMY_ERROR_CODE);
- END (* IF *); (* EWvA: 16/10/93 *)
- (************************* End of CLIP_2 (1) ***********************)
-
- IF CONTINUE THEN
- BEGIN
- (************************* CLIP_2 (2) **************************)
- (** Initialize CODE_STRUCT and the hidden variables of FT, ST, **)
- (** SP, SCN_LINE, SCN_OPTS and DIAG_TBL. **)
- FT_INIT;
- ST_INIT;
- SP_INIT;
- SCN_LINE_INIT;
- SCN_OPTS_INIT;
- DIAGNOST_INIT;
- CODE_STRUCT.LAST_STUB := NIL;
- CODE_STRUCT.FIRST_STUB := NIL;
- (********************* End of CLIP_2 (2) ***********************)
-
- (************************* CLIP_2 (3) **************************)
- (** Prepare a REPORT_FILE file from RUN_INFO.REPORT_FILE_SPEC **)
- (** and raise REPORT_OK if this succeeded. **)
- (* Modified by EWvA on 16/10/93 *)
- IF (RUN_INFO.REPORT_FILE_SPEC.BODY <> EMPTY_STRING_FIXED) AND
- (RUN_INFO.MESSAGE_DESTINATION[1] IN ['R','r','F','f','B','b'])
- (* End of modification dd. 16/10/93 *)
- THEN
- BEGIN
- EXT_FILE_PREP (REPORT_FILE, RUN_INFO.REPORT_FILE_SPEC, GEN_MODE,
- REPORT_OK, ERROR_CODE, ERROR_MSG);
- IF ERROR_CODE <> 0 THEN
- BEGIN
- WRITELN (OUTPUT, ERROR_MSG);
- WRITELN (OUTPUT, 'Continue without report file...');
- WRITELN;
- REPORT_OK := FALSE;
- END
- ELSE
- REPORT_OK := TRUE;
- END
- ELSE (* EWvA: 16/10/93 *)
- REPORT_OK := FALSE; (* EWvA: 16/10/93 *)
- (***************** End of DIAGNOST_EXIT (2) ********************)
-
- START := CLOCK;
- STOP := START;
-
- (************************* CLIP_2 (4) **************************)
- (** Scan the source files as specified in RUN_INFO and build **)
- (** the structure of stubs and slots CODE_STRUCT. LPT_FILE_OK **)
- (** decides if info for the terminal is copied to REPORT_FILE. **)
- WRITELN;
- WRITELN ('============================ ', CLIP_VERSION,
- ' ==========================');
- WRITELN;
- WRITELN ('============================ Busy scanning ',
- '=============================');
- IF REPORT_OK THEN
- BEGIN
- WRITELN (REPORT_FILE);
- WRITELN (REPORT_FILE,
- '============================ ', CLIP_VERSION,
- ' ==========================');
- WRITELN (REPORT_FILE);
- WRITELN (REPORT_FILE,
- '============================ Busy scanning ',
- '=============================');
- END (*IF*);
-
- SCAN_FILES (CODE_STRUCT, RUN_INFO);
-
- WRITELN ('============================ End scanning ',
- '==============================');
- WRITELN;
- IF REPORT_OK THEN
- BEGIN
- WRITELN (REPORT_FILE);
- WRITELN (REPORT_FILE,
- '============================ End scanning ',
- '==============================');
- END (*IF*);
- (********************* End of CLIP_2 (4) **********************)
-
- IF CODE_STRUCT.FIRST_STUB <> NIL THEN
- BEGIN
- (************************* CLIP_2 (5) **********************)
- (** Analyse CODE_STRUCT. LPT_FILE_OK decides if info to the **)
- (** terminal is copied to REPORT_FILE also. **)
- WRITELN ('============================ Busy analysing ',
- '============================');
- IF REPORT_OK THEN
- BEGIN
- WRITELN (REPORT_FILE);
- WRITELN (REPORT_FILE,
- '============================ Busy analysing ',
- '============================');
- END (*IF*);
-
- ANALYSE (CODE_STRUCT);
-
- WRITELN ('============================ End analysing ',
- '=============================');
- WRITELN;
- IF REPORT_OK THEN
- BEGIN
- WRITELN (REPORT_FILE);
- WRITELN (REPORT_FILE,
- '============================ End analysing ',
- '=============================');
- END (*IF*);
- (********************* End of CLIP_2 (5) *******************)
-
- (************************* CLIP_2 (6) **********************)
- (** Generate the modules as specified in RUN_INFO out of **)
- (** CODE_STRUCT. LPT_FILE_OK decides if info for terminal **)
- (** is also copied to REPORT_FILE. **)
- WRITELN ('============================ Busy generating ',
- '===========================');
- IF REPORT_OK THEN
- BEGIN
- WRITELN (REPORT_FILE);
- WRITELN (REPORT_FILE,
- '============================ Busy generating ',
- '===========================');
- END (*IF*);
-
- GENMOD (CODE_STRUCT, RUN_INFO);
-
- WRITELN ('============================ End generating ',
- '============================');
- WRITELN;
- IF REPORT_OK THEN
- BEGIN
- WRITELN (REPORT_FILE);
- WRITELN (REPORT_FILE,
- '============================ End generating ',
- '============================');
- END (*IF*);
- (********************* End of CLIP_2 (6) *******************)
-
- STOP := CLOCK;
- END (*IF*);
-
- (*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- +++++++++++ EWvA, jan6, 1993: Report file ++++++++++++
- FT_INIT_LINE (DUMMY_LINE);
- ST_INIT_SEG (DUMMY_SEG);
- STRING132.LENGTH := 0;
- STRING132.BODY := EMPTY_STRING_FIXED;
- DIAG (WARN, 'CLIP_2 ', DUMMY_LINE, DUMMY_SEG,
- STRING132);
- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*)
-
- (* Generate error messages to terminal and possibly report file *)
- DIAGNOST_EXIT;
-
- (* Delete the segment-table. *)
- ST_FINIT;
-
- (* Display a goodbye message. *)
- WRITELN ('Used (CPU) time :', (STOP-START)/1000:4:2, ' Sec.');
- WRITELN ('See you next time !');
-
- IF REPORT_OK THEN
- BEGIN
- WRITELN (REPORT_FILE, 'Used (CPU) time :',
- (STOP-START)/1000:4:2, ' Sec.');
- WRITELN (REPORT_FILE, 'See you next time !');
- EXT_FILE_CLOSE (REPORT_FILE, DUMMY_ERROR);
- END (*FI*);
- END (*IF*);
- (********************* End of CLIP_2 (body) ********************)
- END (*CLIP_2*).
- (******************* End of module clip_unix.pas *******************)
-